在 PHP 中使用 sqlsrv 防止 SQL 注入
Prevent SQL Injection using sqlsrv in PHP
我对整个 PHP/MSSQL 编码还很陌生,在 SQL 注入预防方面需要帮助。
我正在向使用 MSSQL 数据库的网站添加一个简单的搜索功能。
该代码按我的意愿工作,但它容易受到 SQL 注入。
除了 prepare 语句之外,还有其他保护它的方法吗?
我对存储过程也不太熟悉。
我已经尝试过 prepare 语句但没有成功(除非我做错了什么,这很可能)
我不熟悉的存储过程。
<?PHP
$tech = (isset($_POST['Technician'])? $_POST['Technician'] : null);
$sql = "SELECT * FROM Errors WHERE Error LIKE '%$tech%' or Description LIKE '%$tech%'";
$name = trim($_POST['Technician']);
if(empty($name)){
print '<script type="text/javascript">alert("Please enter an Error Code or Error Description")</script>';
exit;
}
$stmt = sqlsrv_query($conn, $sql);
if ($stmt) {
$rows = sqlsrv_has_rows( $stmt );
if ($rows === true) {
echo "";
} else{
echo '<script type="text/javascript">alert("Please enter a valid Term")</script>';
}
}
while($db_field = sqlsrv_fetch_array($stmt)){
print '<table align="center" style="position: relative; width:250px; text-align: center;">';
print '<tr>';
print '<td><a href="result.php?Error=' . $db_field['Error'] . '">'.$db_field['Error']."</a></td></tr>";
print "<tr>";
print '<td>'.$db_field['Description'].'</td></tr>';
//print "<tr><th>"."Cause"."</th>";
//print "<td>".$db_field['Cause']."</td></tr>";
//print "<tr><th>"."Resolution"."</th>";
//print "<td>".$db_field['Resolution']."</td></tr>";
print "</table><br>";
}
sqlsrv_close($conn);
?>
我预计 SQL 尝试注入时会失败。
使用参数化查询非常简单,只注意?
:
$sql = "SELECT * FROM Errors WHERE Error LIKE ? OR Description LIKE ?";
然后构建一个参数数组,添加 LIKE 通配符 %
:
$params = array("%$tech%", "%$tech%");
使用参数执行:
$stmt = sqlsrv_query( $conn, $sql, $params);
或者,为了其他查询的灵活性,您可以对参数执行以下操作:
$tech = "%$tech%";
$params = array($tech, $tech);
准备好的语句是将原始输入注入 SQL 的最简单方法。如果你愿意,你可以完全跳过它们,但它的代价是更复杂和更低的安全性(你需要自己编写替代代码)。您可以在其他扩展中找到 escape()
函数的唯一原因(或者根本没有机制!)是因为它们是遗留库,有时是非常古老的库。 SQLSRV 相当现代。
此外,您可能想要:
- 用户 filter functions 只需输入支票。
- 转义wildcard characters.
结果代码如下所示:
$tech = filter_input(INPUT_POST, 'Technician');
if ($tech !== null) {
$sql = "SELECT *
FROM Errors
WHERE Error LIKE ? or Description LIKE ?";
$find = '%' . escapeLike($tech) . '%';
$params = [$find, $find];
$res = sqlsrv_query($conn, $sql, $params);
}
function escapeLike($value)
{
return strtr($value, [
'%' => '[%]',
'_' => '[_]',
'[' => '[[]',
]);
}
我对整个 PHP/MSSQL 编码还很陌生,在 SQL 注入预防方面需要帮助。
我正在向使用 MSSQL 数据库的网站添加一个简单的搜索功能。 该代码按我的意愿工作,但它容易受到 SQL 注入。
除了 prepare 语句之外,还有其他保护它的方法吗?
我对存储过程也不太熟悉。
我已经尝试过 prepare 语句但没有成功(除非我做错了什么,这很可能)
我不熟悉的存储过程。
<?PHP
$tech = (isset($_POST['Technician'])? $_POST['Technician'] : null);
$sql = "SELECT * FROM Errors WHERE Error LIKE '%$tech%' or Description LIKE '%$tech%'";
$name = trim($_POST['Technician']);
if(empty($name)){
print '<script type="text/javascript">alert("Please enter an Error Code or Error Description")</script>';
exit;
}
$stmt = sqlsrv_query($conn, $sql);
if ($stmt) {
$rows = sqlsrv_has_rows( $stmt );
if ($rows === true) {
echo "";
} else{
echo '<script type="text/javascript">alert("Please enter a valid Term")</script>';
}
}
while($db_field = sqlsrv_fetch_array($stmt)){
print '<table align="center" style="position: relative; width:250px; text-align: center;">';
print '<tr>';
print '<td><a href="result.php?Error=' . $db_field['Error'] . '">'.$db_field['Error']."</a></td></tr>";
print "<tr>";
print '<td>'.$db_field['Description'].'</td></tr>';
//print "<tr><th>"."Cause"."</th>";
//print "<td>".$db_field['Cause']."</td></tr>";
//print "<tr><th>"."Resolution"."</th>";
//print "<td>".$db_field['Resolution']."</td></tr>";
print "</table><br>";
}
sqlsrv_close($conn);
?>
我预计 SQL 尝试注入时会失败。
使用参数化查询非常简单,只注意?
:
$sql = "SELECT * FROM Errors WHERE Error LIKE ? OR Description LIKE ?";
然后构建一个参数数组,添加 LIKE 通配符 %
:
$params = array("%$tech%", "%$tech%");
使用参数执行:
$stmt = sqlsrv_query( $conn, $sql, $params);
或者,为了其他查询的灵活性,您可以对参数执行以下操作:
$tech = "%$tech%";
$params = array($tech, $tech);
准备好的语句是将原始输入注入 SQL 的最简单方法。如果你愿意,你可以完全跳过它们,但它的代价是更复杂和更低的安全性(你需要自己编写替代代码)。您可以在其他扩展中找到 escape()
函数的唯一原因(或者根本没有机制!)是因为它们是遗留库,有时是非常古老的库。 SQLSRV 相当现代。
此外,您可能想要:
- 用户 filter functions 只需输入支票。
- 转义wildcard characters.
结果代码如下所示:
$tech = filter_input(INPUT_POST, 'Technician');
if ($tech !== null) {
$sql = "SELECT *
FROM Errors
WHERE Error LIKE ? or Description LIKE ?";
$find = '%' . escapeLike($tech) . '%';
$params = [$find, $find];
$res = sqlsrv_query($conn, $sql, $params);
}
function escapeLike($value)
{
return strtr($value, [
'%' => '[%]',
'_' => '[_]',
'[' => '[[]',
]);
}