首页 > 解决方案 > 使用 psycopg2 在 Django 中保护原始 SQL 查询

问题描述

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

查询的简化形式是:

select * from table where {where_clause}

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

为了使查询对 SQL 注入安全,我决定使用psycopg2which 构建查询:

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分成标识符和文字,我也不知道事先所有的列都以这种方式编写。用户可能会选择许多列进行过滤。

我怎样才能使查询安全?

标签: pythonsqldjangosecuritysql-injection

解决方案


首先让用户定义(甚至知道)您的表/列名称似乎并不安全。

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

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

因此,最终用户会向您的后端发送以下过滤器对象:

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

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


推荐阅读