我希望用户能够选择显示的顺序结果,例如按年龄),我不想在从数据库中获取结果后对其进行排序。在
显然,如果用户能够指定影响SQL命令的输入,就需要对其进行清理,我通常会使用参数化,但是pysqlite似乎忽略了除值之外的任何其他参数。在
下面的示例代码显示了参数化不适用于ORDER BY
,以及使用字符串格式的解决方法,但它容易受到SQL注入的影响。在
在不暴露SQLi漏洞的情况下,允许用户输入影响排序顺序的推荐解决方案是什么?我是否必须使用字符串格式并手动检查每个用户的输入?在
#!/user/bin/env python3
import sqlite3
con = sqlite3.connect(':memory:')
cur = con.cursor()
cur.execute('CREATE TABLE test (name, age)')
cur.execute('INSERT INTO test VALUES (:name, :age)', {'name': 'Aaron', 'age': 75})
cur.execute('INSERT INTO test VALUES (:name, :age)', {'name': 'Zebedee', 'age': 5})
cur.execute('SELECT * FROM test ORDER BY age ASC')
results = cur.fetchall()
print('\nGood, but hard coded:\n', results)
# Good, but hard coded:
# [('Zebedee', 5), ('Aaron', 75)]
cur.execute('SELECT * FROM test ORDER BY :order_by ASC', {'order_by': 'age'})
results = cur.fetchall()
print('\norder_by parameter ignored:\n', results)
# order_by parameter ignored:
# [('Aaron', 75), ('Zebedee', 5)]
cur.execute('SELECT * FROM test ORDER BY {order_by} ASC'.format(order_by='age'))
results = cur.fetchall()
print('\nRight order, but vulnerable to SQL injection:\n', results)
# Right order, but vulnerable to SQL injection:
# [('Zebedee', 5), ('Aaron', 75)]
con.close()
SQL参数只用于值;其他任何东西都可能更改查询的含义。(例如,
ORDER BY password
可以留下提示,ORDER BY (SELECT ... FROM OtherTable ...)
也可以)要确保来自客户端的列名有效,可以使用白名单:
但将该字符串集成到查询中仍然是个坏主意,因为验证和实际表可能会不同步,或者您可能会忘记检查。最好从客户端返回一个列索引,这样您使用的实际字符串始终是您自己的,并且在正常测试期间可以很容易地发现任何错误:
^{pr2}$相关问题 更多 >
编程相关推荐