这个 Python 代码是不是容易受到 SQL 注入的影响? (SQLite3)

Posted

技术标签:

【中文标题】这个 Python 代码是不是容易受到 SQL 注入的影响? (SQLite3)【英文标题】:Is this Python code vulnerable to SQL injection? (SQLite3)这个 Python 代码是否容易受到 SQL 注入的影响? (SQLite3) 【发布时间】:2012-11-16 18:34:57 【问题描述】:

正如标题所示,我想知道这段代码是否容易受到 SQL 注入的攻击?如果是这样,是否有更好、更安全的方法来实现同样的目标?

def add(table,*args):
    statement="INSERT INTO %s VALUES %s" % (table,args)
    cursor.execute(statement)

【问题讨论】:

【参考方案1】:

是的,是的。使用这样的东西来防止它:

cursor.execute("INSERT INTO table VALUES ?", args)

请注意,您不能像这样输入表格。理想情况下,表格应该是硬编码的,在任何情况下都不应该来自任何类型的用户输入。您可以使用类似于您对表格所做的字符串,但您最好 100% 确定用户无法以某种方式更改它...有关更多详细信息,请参阅Can I use parameters for the table name in sqlite3?。

本质上,您希望将参数放在游标命令中,因为它可以确保数据数据库安全。使用您的第一个命令,创建一个特殊的tableargs 将一些不安全的东西放入您的SQL 代码中会相对容易。请参阅 python pages 和引用的 http://xkcd.com/327/ 。具体来说,python页面引用:

通常,您的 SQL 操作需要使用 Python 中的值 变量。你不应该使用 Python 的字符串来组装你的查询 操作,因为这样做是不安全的;它使您的程序 容易受到 SQL 注入攻击(请参阅http://xkcd.com/327/ 可能出错的幽默例子)。

改为使用 DB-API 的参数替换。放 ?作为一个 占位符,无论你想在哪里使用一个值,然后提供一个元组 值作为游标的 execute() 方法的第二个参数。 (其他数据库模块可能使用不同的占位符,例如 %s 或 :1.)

基本上,有人可以设置一个执行另一个命令的参数,如下所示:

args="name; DELETE table"

使用 cursor.execute 将填充给定的值,以便参数可以列出,并且当您对其进行查询时,这正是您将得到的。 XKCD 也幽默地解释了这一点。

【讨论】:

谢谢。你能稍微解释一下它为什么容易受到攻击吗? 这可能很明显,但为了安全起见:对所有语句执行此操作,而不仅仅是 INSERT。 SELECT 语句同样容易受到攻击。 5 个赞,被接受,没有人愿意检查? (***.com/questions/5870284/…) 在提供相同的输入(表、参数)字符串的情况下,您能否更详细地解释为什么/如何使用参数 (?) 不会返回与 (%s) 相同的可执行 SQL 代码?跨度> @RyanDalton:使用参数意味着 sqlite3(或您的其他数据库库)可以根据需要绑定参数。它可能只是确保所有内容都被正确引用和转义(可能使用特定于该 DBMS 的功能,否则您很难做到正确)。或者它可能在将 SQL 语句解析为内部格式后实际绑定参数(这可能更快,也更安全)。关键是,任何数据库接口都需要对参数做一些安全的事情,而对于字符串,你必须自己弄清楚并做同样的事情(并且会做错)。

以上是关于这个 Python 代码是不是容易受到 SQL 注入的影响? (SQLite3)的主要内容,如果未能解决你的问题,请参考以下文章

以下代码片段是不是容易受到 Rails 5 中 SQL 注入的影响?

Sql Injection - 以下是不是容易受到攻击?

SQL Server 全文搜索 CONTAINS() 是不是容易受到 SQL 注入的攻击?

json.loads() 是不是容易受到任意代码执行的影响?

参数化的 java 持久性查询是不是容易受到 sql 注入的影响?

此代码是不是容易受到填充预言机攻击?