PyMySQL如何防止用户受到sql注入攻击?

时间:2018-08-02 06:55:57

标签: python sql-injection pymysql server-side-attacks

很抱歉在这里提出问题,但是我找不到关于pymysql安全指南的大量参考资料,这些指南说明了我们如何防止sql注入, 当我进行PHP开发时,我知道使用mysql preparestatement(或称为Parameterized Query或stmt),但是在pymysql中找不到关于此的参考

简单的代码使用pymysql之类的

sqls="select id from tables where name=%s"
attack="jason' and 1=1"
cursor.execute(sqls,attack)

我怎么知道这将阻止或不阻止sql注入攻击?如果阻止成功,pymysql如何阻止?cursor.execute默认已经使用了preparestatement吗?

1 个答案:

答案 0 :(得分:1)

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查询发送到带有参数占位符的数据库,然后分别发送这些参数的值)。风险是程序员会认为将参数的 any 字符串插入到查询字符串中的工作方式与您让驱动程序执行时一样。

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