【发布时间】:2016-05-31 08:05:46
【问题描述】:
我正在转换我的代码以保护它免受 SQL 注入。
目前我已经转换了我的大部分代码并使其正常工作,但我有两个查询让我有点困惑。我正在使用 php 文档here
示例 4 是我认为需要使用的情况。但我不明白这将如何在我准备好的陈述中获得我需要的价值。
我需要更改的第一条语句是,
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 注入。
【问题讨论】:
-
老实说,这就是你需要做的。准备好的语句库负责确保输入到列中的数据是“安全的”,从而防止 SQL 注入。 "Prepared statements are resilient against SQL injection, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, SQL injection cannot occur."
-
所以它只知道如果一个表单发布到页面,无论值是什么都会自动取代?
-
您在执行语句中的数组中指定表单中的值。数组的顺序应与占位符 (
?) 在查询中的顺序相同。 -
好的,谢谢,为了清楚起见,我终于可以继续尝试理解这一点,您介意至少只用我的一个陈述来回答这个问题吗?我真的很感激。我担心我正在做这些工作,最后我不确定是否会阻止 sql 注入。我不担心被黑客入侵,我关心的是从事专业工作并养成良好的习惯。
-
在第一个查询中,您不能使用占位符代替变量,但您应该更加注意清理用户输入。第二个查询对 sql 注入开放,因为您直接将发布的变量注入到您的 sql 中,绝对没有安全检查或清理。准备好的语句的强大之处在于使用占位符、准备要执行的语句以及在运行时替换实际变量。
标签: php mysql sql-server csv pdo