可以使用eval动态构建关联数组吗?

时间:2017-03-30 15:16:44

标签: bash eval associative-array

我知道使用eval执行用户输入字符串是危险的。到目前为止From another question,和测试,似乎动态初始化关联数组的唯一方法是使用eval。

考虑以下示例(例如hash_test.sh),很明显用户输入可用于注入和运行任意命令。

#!/bin/bash

key0="a"
value0="b"
key1='c]="d"); echo "You were hacked on $(date)"; #'
value2="2"
input=$(cat - <<EOF
[$key0]="$value0"
[$key1]="$value1"
EOF
)

eval "declare -A hash=( ${input[@]} )"
echo "keys";
for key in "${!hash[@]}"; do
    echo "Key: $key Value: ${hash[$key]}";
done;

正在运行hash_test.sh演示了此问题。

是否有一种技术可以安全地逃避用户输入以使其安全?

1 个答案:

答案 0 :(得分:3)

首先 - 链接答案中给出的$name = $_POST['scores']; $servername = "localhost"; $username = "root"; $password = ""; $database = "scores"; // $table = "top scores"; // Create connection $conn = new mysqli($servername, $username, $password, $database); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // $sql = "CREATE TABLE score_fish ( // id MEDIUMINT NOT NULL AUTO_INCREMENT, // name CHAR(30) NOT NULL, // score MEDIUMINT, // PRIMARY KEY (id) // )"; $sql = "INSERT INTO score_fish(score) VALUES ($name)"; if ($conn->query($sql) === TRUE) { echo "www.Rados.com.pl"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } ?> <table> <tr> <th class="gameScore">No.</th> <th class="gameScore">Top Scores</th> </tr> <?php $query = "SELECT score FROM score_fish ORDER BY score DESC LIMIT 5;"; if ($conn->query($query) === TRUE) { $score_no = 0; foreach($conn->query($query) as $row){ $score_no += 1; ?> <tr> <th class="gameScore"><?php echo $score_no; ?></th> <th class="gameScore" class="gameScore"><?php echo $row['score']; ?></th> </tr> <?php } //end foreach } else { print ($conn->query($query)); echo "Error: "; } $conn->close(); ?> </table> </section> 对于没有它的eval行为是多余的:

declare

但是,此 具有相同的安全风险:

string='["key1"]="value1" ["key2"]="value2"'
declare -A assoc_array="($string)"
echo "Value of key1 is ${assoc_array[key1]}"

如果您真的坚持,可以引用string='["key1"]="$(touch /tmp/i-am-insecure)"' declare -A assoc_array="($string)" ls -l /tmp/i-am-insecure ## guess what, it exists 生成的值:

printf %q

但最佳做法是迭代填充您的数组。要以完全明确的格式序列化:

printf -v string '[%q]=%q' "key1" '$(touch /tmp/i-am-insecure)'
declare -A assoc_array="($string)"
ls -l /tmp/i-am-insecure ## not found!

...并从该格式反序列化:

for key in "${!array[@]}"; do printf '%s\0' "$key" "${array[$key]}"; done >file