为什么PyMySQL不容易受到SQL注入攻击?

Why is PyMySQL not vulnerable to SQL injection attacks?(为什么PyMySQL不容易受到SQL注入攻击?)
本文介绍了为什么PyMySQL不容易受到SQL注入攻击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不熟悉PyMySQL,刚刚尝试执行查询:

c.execute('''INSERT INTO mysql_test1 (
                                    data,
                                    duration,
                                    audio,
                                    comments
                                ) VALUES (
                                    ?,
                                    ?,
                                    ?,
                                    ?
                                );
                            ''', [
                                    comments_var,
                                    duration_var,
                                    audio_var,
                                    comments_var    
                                ]
                            );

但是,它引发了以下错误:

TypeError: not all arguments converted during string formatting

我注意到我的变量一定有问题,并阅读了如何在PyMySQL中正确处理它们,期望使用参数替换方法,但令我惊讶的是,我什么也找不到。相反,我发现的每个线程都使用字符串操作(例如here、here、here和here(有一条注释声称字符串操作将是PyMySQL的标准操作)。

这对我来说很有趣,因为我以前只处理过SQLite,其中DBAPI文档explicitly warns使用带有变量的字符串操作:

SQL操作通常需要使用来自Python变量的值。但是,请注意不要使用Python的字符串操作来组合查询,因为它们容易受到SQL注入攻击。

文档通过以下代码片段举例说明了这一点:

Never do this -- insecure!
symbol = 'RHAT'
cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
Instead, use the DB-API’s parameter substitution.

当我阅读PyMySQL docs时,我找不到任何关于这种危险的提法。它只是证实了我之前的发现:

如果args是列表或元组,则%s可以用作查询中的占位符。如果args是词典,则%(Name)s可以用作查询中的占位符。

为什么在sqlite3中使用字符串操作容易受到SQL注入攻击,而在pymysql中却没有受到质疑?

推荐答案

很遗憾,pymysql的设计者选择使用%s作为参数占位符。它让许多开发人员感到困惑,因为它与字符串格式化函数中使用的%s相同。但它在pymysql中做的不是同样的事情。

它不仅仅是进行简单的字符串替换。Pymysql将对值应用转义,然后再将它们插入到SQL查询中。这可防止特殊字符更改SQL查询的语法。

事实上,pymysql也会给您带来麻烦。以下是不安全的:

cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)

因为它在将变量symbol作为参数传递给execute()之前将其插入到字符串中。然后,唯一的参数是带有格式化变量的已完成的SQL字符串。

鉴于这是安全的:

cur.execute("SELECT * FROM stocks WHERE symbol = %s", (symbol,))

因为它传递由symbol变量组成的列表作为第二个参数。execute()函数中的代码将转义应用于列表中的每个元素,并将结果值插入到SQL查询字符串中。注意%s不是用单引号分隔的。execute()的代码负责这一点。

这篇关于为什么PyMySQL不容易受到SQL注入攻击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Hibernate reactive No Vert.x context active in aws rds(AWS RDS中的休眠反应性非Vert.x上下文处于活动状态)
Bulk insert with mysql2 and NodeJs throws 500(使用mysql2和NodeJS的大容量插入抛出500)
Flask + PyMySQL giving error no attribute #39;settimeout#39;(FlASK+PyMySQL给出错误,没有属性#39;setTimeout#39;)
auto_increment column for a group of rows?(一组行的AUTO_INCREMENT列?)
Sort by ID DESC(按ID代码排序)
SQL/MySQL: split a quantity value into multiple rows by date(SQL/MySQL:按日期将数量值拆分为多行)