简体   繁体   English

SQL注入漏洞,带有使用串联的准备好的语句

[英]SQL injection vulnerability with prepared statement that uses concatenation

Would parameterized code that uses concatenation in this way have a SQL injection vulnerability? 以这种方式使用串联的参数化代码是否会有SQL注入漏洞? I assume that it would, but I'm not certain what POST data would exploit it. 我认为可以,但是我不确定什么POST数据可以利用它。

        foreach ($_POST as $key => $value) {
          $columns .= ($columns == "") ? "" : ", ";
          $columns .= $key;
          $holders .= ($holders == "") ? "" : ", ";
          $holders .= ":".$value;
        }

        $sql = "INSERT INTO request ($columns) VALUES ($holders)";

        $stmt = $this->pdo->prepare($sql);

        foreach($_POST as $key => $value) {
          $field = ":".$key;
          $stmt->bindValue($field, $value);
        }

        $stmt->execute();

You need an array to store all the columns of request table and check if the post key is present in the array. 您需要一个数组来存储请求表的所有列,并检查数组中是否存在发布键。

PHP code: PHP代码:

$request_columns = array('column1','column2');// all the columns of request table

foreach ($_POST as $key => $value) {
    if(in_array($key,$request_columns)){
          $columns .= ($columns == "") ? "" : ", ";
          $columns .= $key;
          $holders .= ($holders == "") ? "" : ", ";
          $holders .= ":".$key;
     }
}

$sql = "INSERT INTO request ($columns) VALUES ($holders)";

$stmt = $this->pdo->prepare($sql);

foreach($_POST as $key => $value) {
  if(in_array($key,$request_columns)){
      $field = ":".$key;
      $stmt->bindValue($field, $value);
   }
}

$stmt->execute();

@KetanYekale is correct that you need to filter $_POST for known column names. @KetanYekale是正确的,您需要过滤$ _POST以获取已知的列名。

Here's an alternative way of doing it, using some PHP builtin functions. 这是使用一些PHP内置函数的另一种实现方法。

$request_columns = array('column1','column2');// all the columns of request table

# get a subset of $_POST, only those that have keys matching the known request columns
$post_only_columns = array_intersect_key(
  $_POST,
  array_flip($request_column)
);

# make sure columns are delimited like `name` in case they are SQL reserved words
$columns = implode(array_map(function ($col) { return "`$col`"; }, array_keys($post_only_columns), ', ';

# use ? positional holders, not named holders. it's easier in this case
$holders = implode(array_fill(1, count($post_only_columns), '?'), ', ');

$sql = "INSERT INTO request ($columns) VALUES ($holders)";

$stmt => $this->pdo->prepare($sql);

# no need to bindValue() or use a loop, just pass the values to execute()
$stmt->execute( array_values($post_only_columns) );

PHP has many Array functions that you can use in different scenarios to make your code faster and more concise. PHP具有许多Array函数 ,可以在不同情况下使用它们,以使您的代码更快,更简洁。 You can use these functions to avoid writing some types of foreach looping code. 您可以使用这些函数来避免编写某些类型的foreach循环代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM