Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyMySQL如何防止用户遭受sql注入攻击?_Python_Sql Injection_Pymysql_Server Side Attacks - Fatal编程技术网

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

Python PyMySQL如何防止用户遭受sql注入攻击?,python,sql-injection,pymysql,server-side-attacks,Python,Sql Injection,Pymysql,Server Side Attacks,很抱歉在这里询问,但我找不到太多关于pymysql的安全指南的参考资料,关于如何防止sql注入, 当我进行PHP开发时,我知道使用mysql preparedstatement(或者称为参数化查询或stmt),但我在pymysql中找不到关于这方面的参考 简单的代码使用类似pymysql的 sqls="select id from tables where name=%s" attack="jason' and 1=1" cursor.execute(sqls,attack) 我怎么知道这会不

很抱歉在这里询问,但我找不到太多关于pymysql的安全指南的参考资料,关于如何防止sql注入, 当我进行PHP开发时,我知道使用mysql preparedstatement(或者称为参数化查询或stmt),但我在pymysql中找不到关于这方面的参考

简单的代码使用类似pymysql的

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的连接器/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  

攻击sql应该是“jason”和1='1“,我认为这是一个重要的sql注入,应该是“jason”或1='1”。如果您使用AND,结果不会改变。这不是为什么您围绕低级驱动程序创建包装器以提供高级接口和数据验证的原因吗?如果编写包装器的开发人员了解如何编写安全代码,那么当然。谢谢Karwin,这解决了我的困惑,很高兴收到您的答案,祝您愉快!!很乐意帮忙。顺便说一句,习惯上堆栈溢出是向上投票或接受对您有帮助的答案。