php - 保护 CSV 文件的 SQL 插入免受 SQL 注入(inject)

标签 php mysql sql-server csv pdo

我正在转换我的代码以保护它免受 SQL 注入(inject)攻击。

目前我已经转换了大部分代码并使其正常工作,但我有两个问题让我有点困惑。我正在使用 php 文档 here

示例 4 是我认为需要使用的情况。但我不明白这将如何在我准备好的陈述中获得我需要的值(value)。

我需要更改的第一个语句是,

require_once('Dbconfig.php');

$limit  = (intval($_GET['limit']) != 0) ? $_GET['limit'] : 5;
$offset = (intval($_GET['offset']) != 0) ? $_GET['offset'] : 0;

$sql = "SELECT * FROM wuno_inventory WHERE 1 ORDER BY id ASC LIMIT $limit OFFSET $offset";
try {
    $stmt = $DB_con->prepare($sql);
    $stmt->execute();
    $results = $stmt->fetchAll();
}
catch (Exception $ex) {
    echo $ex->getMessage();
}
if (count($results) > 0) {
    foreach ($results as $res) {
        echo '<tr class="invent">';
        echo '<td>' . $res['wuno_product'] . '</td>';
        echo '<td>' . $res['wuno_alternates'] . '</td>';
        echo '<td>' . $res['wuno_description'] . '</td>';
        echo '<td>' . $res['wuno_onhand'] . '</td>';
        echo '<td>' . $res['wuno_condition'] . '</td>';
        echo '</tr>';
    }
}
?>

我需要转换的第二个语句是,

<?php
require_once ('Dbconfig.php');

$limit = (intval($_GET['limit']) != 0 ) ? $_GET['limit'] : 5;
$offset = (intval($_GET['offset']) != 0 ) ? $_GET['offset'] : 0;

if(!empty($_POST["itemID"])) {
 $sql=" SELECT * FROM wuno_inventory WHERE wuno_product like '%". $_POST["itemID"] ."%' OR wuno_alternates like '%". $_POST["itemID"] ."%' ORDER BY wuno_product ASC LIMIT $limit OFFSET $offset ";
try {
  $stmt = $DB_con->prepare($sql);
  $stmt->execute();
  $results = $stmt->fetchAll();
} catch (Exception $ex) {
  echo $ex->getMessage();
}
if (count($results) > 0) {
  foreach ($results as $res) {
    echo '<tr class="invent">';  
    echo '<td>' . $res['wuno_product'] . '</td>';  
    echo '<td>' . $res['wuno_alternates'] . '</td>';  
    echo '<td>' . $res['wuno_description'] . '</td>';  
    echo '<td>' . $res['wuno_onhand'] . '</td>';  
    echo '<td>' . $res['wuno_condition'] . '</td>';  
    echo '</tr>';   
  }
}
}
?>

这是我尝试使用的示例,

<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if ($stmt->execute(array($_GET['name']))) {
  while ($row = $stmt->fetch()) {
    print_r($row);
  }
}
?>

我不明白在语句中添加 ? 的方式和原因。它真的告诉我我需要做的就是在我的两个列名所在的位置添加 ? 吗?请告诉我如何将这两个语句转换为准备好的语句以防止 sql 注入(inject)。

最佳答案

准备好的语句库负责确保输入到列中的数据是“安全的”,从而防止 SQL 注入(inject)。

以下是您如何在一个代码示例中使用占位符 (?) 作为准备好的语句:

if(!empty($_POST["itemID"])) {
 $sql=" SELECT * FROM wuno_inventory WHERE wuno_product like ? OR wuno_alternates like ? ORDER BY wuno_product ASC LIMIT $limit OFFSET $offset ";
try {
      $stmt = $DB_con->prepare($sql);
      $stmt->execute(array('%'.$_POST['itemID'].'%','%'.$_POST['itemID'].'%')); // two placeholders in the query means two items in the array
      $results = $stmt->fetchAll();
    } catch (Exception $ex) {
       echo $ex->getMessage();
    }
}

阅读更多关于 Demystifying PDO 的信息.

YOU MUST pass all values to bind in an array to PDOStatement->execute() or you have to bind every value with PDOStatement->bindValue(), then call PDOStatement->execute() with no parameters. Passing an array (empty or not) to execute() will replace any previous bindings and can lead to errors, e.g. with MySQL the error "SQLSTATE[HY000]: General error: 2031" (CR_PARAMS_NOT_BOUND) if you passed an empty array.

关于php - 保护 CSV 文件的 SQL 插入免受 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35493635/

相关文章:

php - 使用 Zend Framework 创建 cronjob

php - 如何在 Laravel 中显示多个 Toast 通知

php - 设置 LAMP 服务器,phpmyadmin 出现问题“无法加载或保存配置”

sql - 交叉连接同一表中的 N 组行

sql-server - 数据流中的SSIS变量使用问题

sql-server - SQL多次插入同一行

php - php echo 变音符号问题

MySQL 事件 If 语句 END IF 错误

mysql - 通过 SSL 将 phpMyAdmin 连接到 MySQL 服务器

mysql - 将 Flash 中的 Actionscript 3 连接到数据库的最佳方法是什么?