简体   繁体   English

这个Python代码是否容易受到SQL注入攻击? (sqlite3的)

[英]Is this Python code vulnerable to SQL injection? (SQLite3)

As the title suggests, I would like to know if this code is vulnerable to SQL Injection? 正如标题所示,我想知道这段代码是否容易受到SQL注入攻击? And if so, is there a better, more secure, way of achieving the same thing? 如果是这样,是否有更好,更安全的方式来实现同样的目标?

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

Yes, it is. 是的。 Use something like this to prevent it: 使用这样的东西来防止它:

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

Note that you cannot enter the table in like this. 请注意,您不能像这样输入表格。 Ideally the table should be hard coded, in no circumstance should it come from a user input of any kind. 理想情况下,表格应该是硬编码的,在任何情况下都不应该来自任何类型的用户输入。 You can use a string similar to what you did for the table, but you'd better make 100% certain that a user can't change it somehow... See Can I use parameters for the table name in sqlite3? 您可以使用类似于您对表所做的字符串,但您最好100%确定用户无法以某种方式更改它...请参阅我可以在sqlite3中使用参数作为表名吗? for more details. 更多细节。

Essentially, you want to put the parameters in the cursor command, because it will make sure to make the data database safe. 实际上,您希望将参数放在cursor命令中,因为它确保使数据库安全。 With your first command, it would be relatively easy to make a special table or args that put something into your SQL code that wasn't safe. 使用第一个命令,制作一个特殊的tableargs可以相对容易地将一些东西放入SQL代码中并且不安全。 See the python pages , and the referenced http://xkcd.com/327/ . 请参阅python页面和引用的http://xkcd.com/327/ Specifically, the python pages quote: 具体来说,python页面引用:

Usually your SQL operations will need to use values from Python variables. 通常,您的SQL操作需要使用Python变量中的值。 You shouldn't assemble your query using Python's string operations because doing so is insecure; 你不应该使用Python的字符串操作来组装你的查询,因为这样做是不安全的; it makes your program vulnerable to an SQL injection attack (see http://xkcd.com/327/ for humorous example of what can go wrong). 它使您的程序容易受到SQL注入攻击(请参阅http://xkcd.com/327/以获取可能出错的幽默示例)。

Instead, use the DB-API's parameter substitution. 而是使用DB-API的参数替换。 Put ? 放? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor's execute() method. 作为占位符,无论您想要使用哪个值,然后提供一个值元组作为游标的execute()方法的第二个参数。 (Other database modules may use a different placeholder, such as %s or :1.) (其他数据库模块可能使用不同的占位符,例如%s或:1。)

Basically, someone could set an args that executed another command, something like this: 基本上,有人可以设置执行另一个命令的args,如下所示:

args="name; DELETE table"

Using cursor.execute will stuff the value given, so that the argument could be as listed, and when you do a query on it, that is exactly what you will get out. 使用cursor.execute将填充给定的值,以便参数可以列出,当您对其进行查询时,这正是您将要获得的。 XKCD explains this humorously as well. XKCD也幽默地解释了这一点。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM