PyMySQL 如何防止用户受到 sql 注入攻击?
How do PyMySQL prevent user from sql injection attack?
很抱歉在这里提问,但我找不到太多关于 pymysql 安全指南的参考资料,关于我们如何防止 sql 注入,
当我做 PHP develope 我知道使用 mysql preparedstatement(或称为参数化查询或 stmt),但我在 pymysql
中找不到关于这个的参考
简单代码使用pymysql like
sqls="select id from tables where name=%s"
attack="jason' and 1=1"
cursor.execute(sqls,attack)
我怎么知道这会阻止sql注入攻击?如果阻止成功,pymysql如何阻止?cursor.execute是否已经默认使用preparedstatement?
Python 驱动程序不使用真正的查询参数。在 python 中,参数(您的示例中的变量 attack
)在将 SQL 发送到数据库服务器之前插入到 SQL 字符串中。
这与使用查询参数不同。在真正的参数化查询中,SQL 字符串与参数占位符一起发送到数据库服务器。
但是 Python 驱动程序在插入时确实正确地转义了参数,这可以防止 SQL 注入。
我打开查询日志就可以证明:
mysql> SET GLOBAL general_log=ON;
并在我 运行 Python 脚本时跟踪日志:
$ tail -f /usr/local/var/mysql/bkarwin.log
...
180802 8:50:47 14 Connect root@localhost on test
14 Query SET @@session.autocommit = OFF
14 Query select id from tables where name='jason\' and 1=1'
14 Quit
您可以看到查询已将值插入其中,嵌入的引号字符前面有一个反斜杠,这可以防止它成为 SQL 注入向量。
我实际上正在测试 MySQL 的 Connector/Python,但是 pymysql 做同样的事情。
我不同意 Python 连接器的设计决定,以避免使用真实的查询参数(即真实参数通过将 SQL 查询发送到带有参数占位符的数据库,并发送值来工作分别针对这些参数)。风险在于,程序员会认为 任何 参数到查询字符串的字符串插值与您让驱动程序执行时的效果相同。
SQL 注入漏洞示例:
attack="jason' and '1'='1"
sqls="select id from tables where name='%s'" % attack
cursor.execute(sqls)
日志显示这导致 SQL 注入:
180802 8:59:30 16 Connect root@localhost on test
16 Query SET @@session.autocommit = OFF
16 Query select id from tables where name='jason' and '1'='1'
16 Quit
很抱歉在这里提问,但我找不到太多关于 pymysql 安全指南的参考资料,关于我们如何防止 sql 注入, 当我做 PHP develope 我知道使用 mysql preparedstatement(或称为参数化查询或 stmt),但我在 pymysql
中找不到关于这个的参考简单代码使用pymysql like
sqls="select id from tables where name=%s"
attack="jason' and 1=1"
cursor.execute(sqls,attack)
我怎么知道这会阻止sql注入攻击?如果阻止成功,pymysql如何阻止?cursor.execute是否已经默认使用preparedstatement?
Python 驱动程序不使用真正的查询参数。在 python 中,参数(您的示例中的变量 attack
)在将 SQL 发送到数据库服务器之前插入到 SQL 字符串中。
这与使用查询参数不同。在真正的参数化查询中,SQL 字符串与参数占位符一起发送到数据库服务器。
但是 Python 驱动程序在插入时确实正确地转义了参数,这可以防止 SQL 注入。
我打开查询日志就可以证明:
mysql> SET GLOBAL general_log=ON;
并在我 运行 Python 脚本时跟踪日志:
$ tail -f /usr/local/var/mysql/bkarwin.log
...
180802 8:50:47 14 Connect root@localhost on test
14 Query SET @@session.autocommit = OFF
14 Query select id from tables where name='jason\' and 1=1'
14 Quit
您可以看到查询已将值插入其中,嵌入的引号字符前面有一个反斜杠,这可以防止它成为 SQL 注入向量。
我实际上正在测试 MySQL 的 Connector/Python,但是 pymysql 做同样的事情。
我不同意 Python 连接器的设计决定,以避免使用真实的查询参数(即真实参数通过将 SQL 查询发送到带有参数占位符的数据库,并发送值来工作分别针对这些参数)。风险在于,程序员会认为 任何 参数到查询字符串的字符串插值与您让驱动程序执行时的效果相同。
SQL 注入漏洞示例:
attack="jason' and '1'='1"
sqls="select id from tables where name='%s'" % attack
cursor.execute(sqls)
日志显示这导致 SQL 注入:
180802 8:59:30 16 Connect root@localhost on test
16 Query SET @@session.autocommit = OFF
16 Query select id from tables where name='jason' and '1'='1'
16 Quit