使用 psycopg2 在 Django 中保护原始 SQL 查询

Secure raw SQL query in Django with psycopg2

我正在使用 Django 框架创建 Web 应用程序。在 SQL 查询之一中,我必须连接多个表并使用用户输入作为“where”子句的一部分来获取结果。由于查询相当复杂,我选择使用原始 SQL 而不是 django 框架。

查询的简化形式是:

select * from table where {where_clause}

where_clause 会是 col1>100 and col2>50 and col3 <40 等形式 这部分是根据用户输入在前端创建的(有点像股票筛选器)。

为了使查询安全地防止 SQL 注入,我决定使用 psycopg2 将查询构建为:

query = sql.SQL("select {field} from {table} where {pkey} = %s").format(
    field=sql.Identifier('my_name'),
    table=sql.Identifier('some_table'),
    pkey=sql.Identifier('id'))

即使我把where_clause的所有部分都分成标识符和文字,我也不知道所有的列都是这样写的。可能有很多列可供用户选择过滤。

我怎样才能使查询安全?

让用户定义(或什至知道)您的 tables/columns 名称一开始似乎并不安全。

我会创建一些允许值的字典,用户可以通过该映射过滤到您数据库中的实际表(这样用户就不知道您的数据库列名称)。

然后,我不会让用户直接编写“>”、“<”等运算符,而是为用户提供一个比较运算符的下拉列表供用户使用。

所以最终用户会向您的后端发送一个后续过滤器对象:

{
  “Field name 1”: {“value”: “some value”, “comparison_operator”: “greater_than”,
  “Filed name 2”: ...
}

然后在您的后端将这些值转换为 sql where 子句