使用 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 子句
我正在使用 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 子句