首页 > 解决方案 > php: sql-injection > 无法使用prepared statement时如何防止?

问题描述

一个简单的问题:我有一个不使用准备好的语句(mySQLi)的框架。当我有一些用户输入(通过公共表单进行但不允许 HTML 代码)时,如何避免 sql 注入。该评论必须存储在 mysqli 数据库中。

检测和删除可能的注入代码的最佳做法是什么?请不要建议使用准备好的语句,如果不重写整个框架,它们是不可用的!

编辑

我不是在问如何进行 MySQLi 查询!我问如何防止 php 级别的 sql 注入。重复一遍:一些网站访问者在纯文本字段中留下评论。在此评论中,此访问者(脚本小子)认为,他可以发布 sql-injection。

现在再说一遍:在将其添加到数据库之前如何从评论中删除此伪代码。诸如“嘿,使用准备好的语句”、“使用 pdo”、“使用这种带有这些参数的查询”之类的答案并没有回答我的问题。还有像“改变”你的框架“或不够用的答案!

我知道这样的代码可以被 preg_replace(..) 等删除。是的,我知道这里有些人不使用这种技术的意见..所以最好不要朝那个方向回答!

标签: phpprepared-statementsql-injection

解决方案


您可能认为在每个输入上使用mysqli::real_escape_string()之类的“转义”函数与使用准备好的语句一样安全。

除了:

  • 转义不适用于数字输入,仅适用于带引号的字符串和带引号的日期。

  • 转义有一些意想不到的情况,它不起作用。这些是边缘情况,但它们存在。请参阅有关mysql_real_escape_string()的 SQL 注入答案中的一些示例

  • 编写代码时转义更难。正确地做是费时费力的,而且容易出错。开发人员经常想跳过它。

关心防止 SQL 注入的开发人员建议使用查询参数来代替,原因有几个,包括但不限于以下几点:

  • 查询参数也适用于数值。

  • 使用查询参数的代码更易于编写和阅读,并且不易出错。我们希望开发者一旦养成了使用查询参数的习惯,使用这种方式的可靠性会更高,漏洞的可能性也会降低。

例如,您可以编写如下代码:

$sql = "INSERT INTO mytable (col1, col2, col3, col4, col5, col6) 
  VALUES ('" . mysqli_real_escape_string($_POST['col1']) . "', " 
  . $mysqli->real_escape_string($_POST['col2']) . "', '" 
  . $mysqli->real_escape_string($_POST['col3']) . "', '" 
  . $mysqli->real_escape_string($_POST['col4']) . ", '" 
  . $mysqli->real_escape_string($_POST['col5']) . "', '" 
  . $mysqli->real_escape_string($_POST['col6']) . "')";

你能发现错误吗?有足够的时间,我相信你可以。但它会减慢你的编码速度,并且在你寻找丢失的引号字符和其他错误时可能会让你眼睛疲劳。

但是这样写要容易得多,之后也更容易阅读:

$sql = "INSERT INTO mytable (col1, col2, col3, col4, col5, col6) 
  VALUES (?, ?, ?, ?, ?, ?)";

查询参数对于更多数据类型是安全的,它们可以帮助您更快地编写代码,减少错误。这是一个很大的胜利。

与上面的其他评论一样,我不同意您关于 MySQLi 不支持查询参数的说法。它清楚地显示在文档中:https ://www.php.net/manual/en/mysqli.prepare.php

如果您有一些使用 MySQLi 但​​不支持的包装器代码mysqli::prepare(),那么我建议您停止使用该包装器代码。要么为你的框架编写特性以便它使用查询参数,要么得到另一个框架。


还有像“改变”你的框架“或不够用的答案!

看,这是事实:如果你不能编写安全地处理用户输入的代码,那么你就不应该接受用户输入。

您认为有使用方法,preg_replace()但没有。注入代码的方法有很多种(SQL 或 Javascript),最终您也会过滤掉许多合法的用户评论。如果您的 Web 应用程序从他们的评论中去掉引号和撇号,您的用户会有什么反应?您还需要删除哪些其他字符?

查询参数是这个问题最有效的解决方案。你对他们的抵制是荒谬的。

这就像一个电工问,“我怎样才能防止被电击?但我不能使用绝缘手套或工具,所以不要这么建议。”


推荐阅读