admin

SQL查询参数化如何工作?

sql

我问这个问题有点傻,因为我似乎是世界上唯一一个不了解这个问题的人,但是无论如何,这都是可行的。我将以Python为例。当我使用原始SQL查询(通常使用ORM)时,我会使用参数化,例如使用SQLite的以下示例:

方法A:

username = "wayne"
query_params = (username)
cursor.execute("SELECT * FROM mytable WHERE user=?", query_params)

我知道这可行,我知道这是通常推荐的方式。SQL注入易受攻击的方式可以执行以下操作:

方法B:

username = "wayne"
cursor.execute("SELECT * FROM mytable WHERE user='%s'" % username)

到目前为止,我可以告诉我了解SQL注入,如本Wikipedia文章中所述。我的问题很简单:方法A与方法B有什么真正的不同?为什么方法A的最终结果与方法B不同?我假设该cursor.execute()方法(Python的DB-
API规范的一部分)负责正确地对输入进行转义和类型检查,但这从未在任何地方明确声明。在这种情况下,所有这些参数化就是吗?对我来说,当我们说“参数化”时,所有的意思就是“字符串替换”,例如%格式。那不对吗?


阅读 154

收藏
2021-05-10

共1个答案

admin

参数化查询实际上并不执行字符串替换。如果使用字符串替换,则SQL引擎实际上会看到类似以下的查询

SELECT * FROM mytable WHERE user='wayne'

如果使用?参数,则SQL引擎会看到如下查询

SELECT * FROM mytable WHERE user=<some value>

这意味着,即使在看到字符串“ wayne”之前,它也可以完全解析查询并大致了解查询的功能。它将“
wayne”粘贴到它自己的查询表示中,而不是描述查询的SQL字符串中。因此,SQL注入是不可能的,因为我们已经通过了该过程的SQL阶段。

(以上是概括性的,但或多或​​少传达了这个想法。)

2021-05-10