可以用 SELECT 语句中的单个单词进行 SQL 注入吗?

Can an SQL injection be made with a single word in a SELECT statement?

假设您有一个如下所示的查询:

SELECT * FROM messages WHERE sender='clean_username'

其中 clean_username 通过 get/post 接收并像这样进行清理:

$clean_username = preg_replace( '/[^A-Za-z0-9_]+/m' , '', $dirty_username );

以上代码删除了所有空格(除其他外),这意味着 valid_username 参数将始终只有一个单词。

可以通过注入利用的最简单方法是什么?

我问这个问题是为了更好地理解 SQL 注入的工作原理。在我的工作中,我坚持使用准备好的语句和参数化查询来防止注入的既定良好做法,但我认为人们也了解如何在像这样的简单场景中注入恶意代码是有好处的。

您仍然可以使用十六进制编码来利用它:去除空格是不够的。 I guess this is a somewhat interesting place to start。但是请考虑 preg_match()es 对于高流量站点的性能来说非常糟糕。

准备好的语句和参数化查询始终是防止 SQL 注入的最佳方法。

使用十六进制编码且无空格的 GET 注入示例

?id=(1)and(1)=(0)union(select(null),group_concat(column_name),(null)from(information_schema.columns)where(table_name)=(0x7573657273))#

我想你可以看到上面的问题。

我想你已经自己回答了这个问题。

最好的方法是使用参数化查询来区分用户数据和 sql 命令的标准方法。

在您的特定情况下,您假设发件人用户名只能由一组有限的 ASCII 字符组成。这可能暂时有效,只要之前没有字符串转换,就没有人可以轻易关闭 sql 语句中的字符串撇号。

但始终要考虑对变化的预期。在不久的将来,有人可以依赖您提供的代码并使用或修改它并做出新的假设。您的测试实际上很薄弱,当没有人记得并没有预料到它时,它可能会突然变得危险。