You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用psycopg2的sql.SQL与sql.Literal避免IN子句SQL注入?

解决方法

直接用字符串拼接SQL语句不仅会导致单引号处理错误,还存在严重的SQL注入风险。用psycopg2.sql模块的SQL和Literal可以安全处理这类场景,具体实现如下:

正确代码示例

from psycopg2 import sql

# 获取用户传入的国家数组
countries = query["countries"]

# 处理空数组的边界情况(避免IN()语法错误)
if not countries:
    # 返回空结果集
    cursor.execute("SELECT * FROM contact WHERE 1=0;")
else:
    # 构造安全的SQL查询
    query = sql.SQL("SELECT * FROM contact WHERE country IN ({})").format(
        sql.SQL(",").join(map(sql.Literal, countries))
    )
    cursor.execute(query)

关键逻辑说明

  • sql.SQL():用于定义静态的SQL模板部分,确保这部分内容不会被当成用户输入解析,从根源避免注入风险。
  • sql.Literal():将每个用户传入的国家名称转换为安全的SQL字面量,自动处理单引号转义(比如把O'Neil转成'O''Neil'),解决单引号导致的语法错误。
  • sql.SQL(",").join(...):把多个Literal对象用逗号连接,生成合法的IN子句参数列表。

原写法的问题

你之前的字符串拼接方式:

query = "SELECT * FROM contact WHERE country IN ('{}');".format("', '".join(query["countries"]))
  • 当国家名称包含单引号时,会直接破坏SQL语法结构,导致查询报错。
  • 若用户传入恶意构造的内容(比如'); DROP TABLE contact;--),会直接执行危险的SQL操作,引发数据安全问题。

内容的提问来源于stack exchange,提问作者Gaut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:09:53