0

像这样使用 update_user 函数是否安全?

function update_user($update_data) {
    global $pdo;

    $update = array();

    foreach($update_data as $field=>$data){
    $update[] = '`'. $field.'` = \''. $data.'\''; 
    }
    $query = $pdo->prepare("UPDATE users SET " . implode(', ', $update) ."WHERE user_id = " .$_SESSION['user_id']);
    $query->execute(); 
}
4

2 回答 2

1

当然不是。
标识符和字符串的格式不充分。
并且您没有使用将 PDO 与旧扩展区分开来的占位符。

PDO 标签 wiki中,您可以找到一个使用辅助函数执行此任务的示例。
从那里使用一个函数,你可以这样做

这个函数可以这样使用:

function update_user($allowed) {
    global $pdo;
    $allowed = array("name","surname","email","password"); // allowed fields
    $sql = "UPDATE users SET ".pdoSet($allowed,$values)." WHERE id = :id";
    $stm = $pdo->prepare($sql);
    $values["id"] = $_SESSION['user_id'];
    $stm->execute($values);
}
// usage:
update_user();

请注意,此函数将直接从 $_POST 数组中获取值,因此需要提及两件重要的事情:

  • 无需手动创建 $input_data
  • 如果 $_POST 数组中缺少字段(例如散列密码),则必须手动添加它们。

但是,如果您已将您的$input_data白名单列入白名单(即在脚本中创建所有字段名称硬编码),也可以使用 deceze 的解决方案。
但是如果$input_data来自客户端,他的解决方案很容易受到 SQL 注入

于 2013-03-03T13:43:26.410 回答
-1

不,您使用准备好的语句是没有意义的,并且数据不会被转义。使用正确准备的语句,如下所示:

$fields = array_map(function ($key) { return "`$key` = :$key"; }, array_keys($update_data));
$query  = sprintf('UPDATE users SET %s WHERE user_id = :userId', join(', ', $fields));
$stmt   = $pdo->prepare($query);

forach ($update_data as $key => $value) {
    $stmt->bindValue(":$key", $value);
}
$stmt->bindParam(':userId', $_SESSION['user_id']);

$stmt->execute();

这至少假设数组键是白名单值,不会导致语法问题。

于 2013-03-03T13:46:23.223 回答