我正在转换我的代码以保护它免受 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 withPDOStatement->bindValue()
, then callPDOStatement->execute()
with no parameters. Passing an array (empty or not) toexecute()
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/