我应该如何在pysqlite中参数化列名以避免SQL注入

时间:2017-01-25 11:19:28

标签: python sql sqlite sql-injection pysqlite

我希望用户能够选择显示的订单结果,例如按年龄),我不想在从数据库中获取它们之后对它们进行排序。

显然,如果用户能够指定影响SQL命令的输入,则需要对其进行清理,我通常会使用参数化,但是pysqlite似乎忽略除了值之外的任何参数。

下面的示例代码显示参数化不适用于try\catch,也是使用字符串格式化的解决方法,但这很容易受到SQL注入的影响。

建议的解决方案是什么是允许用户输入影响排序顺序而不暴露SQLi漏洞?我是否必须使用字符串格式并手动检查每个用户输入?

ORDER BY

1 个答案:

答案 0 :(得分:3)

SQL参数仅用于值;其他任何东西都可能改变查询的含义。 (例如,ORDER BY password可以留下提示,ORDER BY (SELECT ... FROM OtherTable ...)也可以。)

要确保客户端的列名有效,您可以使用白名单:

if order_by not in ['name', 'age']:
    raise ...
execute('... ORDER BY {}'.format(order_by))

但是将该字符串集成到查询中仍然是一个坏主意,因为验证和实际表可能不同步,或者您可能忘记检查。最好从客户端返回列索引,以便您使用的实际字符串始终是您自己的,并且在正常测试期间可以轻松找到任何错误:

order_by = ['name', 'age'][order_index]
execute('... ORDER BY {}'.format(order_by))