psycopg2 和 SQL 注入安全性

问题描述 投票:0回答:3

我正在编写一个类,用作更大的建模算法的一部分。我的部分进行空间分析来计算从某些点到其他点的距离。条件有多种,包括返回距离、截止距离等

目前,项目规范仅指示硬编码的情况。即“函数 #1 需要列出 500m 范围内从点集 A 到点集 B 的所有距离。函数 #2 需要列出从点集 C 到点集 D 的所有距离...”等等。

我不想硬编码这些参数,开发模型下一阶段的人也不想硬编码,因为显然他们想调整参数,或者可能在其他项目中重复使用该算法,在这些项目中他们会有不同的算法条件。

现在的问题是我正在使用 psycopg2 来执行此操作。这是我工作的标准,所以我没有选择偏离它。我读到,由于 SQL 注入的明显原因,暴露将作为参数放入执行查询中的参数是一个非常糟糕的主意。然而,我认为 psycopg2 会自动清理 SQL 输入。我认为问题在于使用

AsIs
函数。

简单的解决方案就是按照项目中指定的方式对其进行硬编码,但这对我来说感觉很懒惰和草率。我不喜欢做懒惰和马虎的工作。

允许用户输入将输入到 psycopg2 执行的查询中的参数是否安全?或者只是使用

AsIs
使其不安全?如果我想让用户能够输入这些参数,我是否必须自己负责对输入进行清理,如果是这样,是否有一种快速简便的方法来做到这一点,就像使用另一个 python 库或什么东西?

python postgresql postgis psycopg2
3个回答
49
投票

AsIs
是不安全的,除非你真的知道自己在做什么。例如,您可以将其用于单元测试。

传递参数并不是那么不安全,只要你不预先格式化你的sql查询。永远不要这样做:

sql_query = 'SELECT * FROM {}'.format(user_input)
cur.execute(sql_query)

因为

user_input
可能是
';DROP DATABASE;'

相反,请执行以下操作:

sql_query = 'SELECT * FROM %s'
cur.execute(sql_query, (user_input,))

pyscopg2
将清理您的查询。此外,如果您确实不信任用户的输入,您可以使用自己的逻辑预先清理代码中的参数。

根据

psycopg2
的文档

警告永远、永远、永远不要使用 Python 字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL 查询字符串。即使是在枪口下也不行。

此外,我永远不会让我的用户告诉我应该查询哪个表。您的应用程序的逻辑(或路线)应该告诉您这一点。

关于

AsIs()
,根据
psycopg2
的文档

Asis()...适用于其字符串表示形式已经作为 SQL 表示形式有效的对象。

所以,不要将其与用户输入一起使用。


7
投票

您可以使用 psycopg2.sql 来编写动态查询。与

AsIs
不同,它会保护您免受 SQL 注入。


6
投票

如果您需要将查询存储在变量中,您可以使用

SQL
方法(文档):

from psycopg2 import sql


query = sql.SQL("SELECT * FROM Client where id={clientId}").format(clientId=sql.Literal(clientId))
© www.soinside.com 2019 - 2024. All rights reserved.