moy*_*260 4 python sql postgresql sql-injection psycopg2
在 Python 中使用 Psycopg2 和以下代码:
import psycopg2
import getpass
conn = psycopg2.connect("dbname=mydb user=%s" % getpass.getuser())
cursor = conn.cursor()
tables = ["user", "group", "partner", "product"]
for table in tables:
# with sql injection
cursor.execute("SELECT name FROM %s LIMIT 1" % (table,))
print "table", table, "result", len(cursor.fetchone())
# without sql injection
cursor.execute("SELECT name FROM %s LIMIT 1", (table,))
print "table", table, "result", len(cursor.fetchone())
Run Code Online (Sandbox Code Playgroud)
输出是:
table res_partner result 1
Traceback (most recent call last):
File "my_psycopg2_example.py", line 16, in <module>
cursor.execute("SELECT name FROM %s LIMIT 1", (table,))
psycopg2.ProgrammingError: syntax error at or near "'res_partner'"
LINE 1: SELECT name FROM 'res_partner' LIMIT 1
Run Code Online (Sandbox Code Playgroud)
使用 SQL 注入它工作正常。
但我们不想造成安全问题。
我们阅读了此文档,并在其中找到了以下评论:
只应通过此方法绑定变量值:不应使用它来设置表或字段名称。对于这些元素,在运行之前应该使用普通的字符串格式
execute()。
但是如果我们使用“普通字符串格式”,我们也会有 SQL 注入。
管理这种特殊情况并避免 SQL 注入的好方法是什么?
我认为您混淆了 SQL 注入的定义。SQL 注入是对您的软件的一种攻击,其中有人使您的 SQL 查询执行您不希望它执行的操作。字符串插值不是 SQL 注入。字符串插值有时可以启用 SQL 注入,但并非总是如此。要了解字符串插值并不总是不安全,请考虑以下哪项最安全:
sql = 'SELECT name FROM user'sql = 'SELECT name FROM ' + 'user'sql = 'SELECT name FROM %s' % ['user']sql = 'SELECT name FROM {}'.format('user')这些代码行中的每一行都做完全相同的事情,因此它们中的任何一条都不会比其他代码更安全或更不安全。在您的确切示例中,没有 SQL 注入的危险,因为您只是在构建硬编码的 SQL 查询字符串。
另一方面,如果您的table价值来自用户,则可能存在安全问题:
如果他们传递存在的表的名称,但您不希望他们查询怎么办?
table = 'secrets'
sql = 'SELECT name FROM %s LIMIT 1' % table
Run Code Online (Sandbox Code Playgroud)
结果是:
SELECT name FROM secrets LIMIT 1
Run Code Online (Sandbox Code Playgroud)如果他们传递的东西实际上不是表名怎么办?
table = 'product; DROP TABLE user; --'
sql = 'SELECT name FROM %s LIMIT 1' % table
Run Code Online (Sandbox Code Playgroud)
结果是:
SELECT name FROM product;
DROP TABLE user;
-- LIMIT 1
Run Code Online (Sandbox Code Playgroud)您可以通过检查表名是否允许来防止这种情况:
if table.lower() not in ["user", "group", "partner", "product"]:
raise Something('Bad table name: %r' % table)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8465 次 |
| 最近记录: |