You need to enable JavaScript to run this app. Python SQLite3如何基于用户输入安全查询表且无SQL注入风险?
优惠活动
大模型
产品
解决方案
定价
更多

Python SQLite3如何基于用户输入安全查询表且无SQL注入风险?

SQL注入风险规避方案

核心原因说明

参数化查询的占位符仅支持传入数据值,会自动对传入内容加引号、做数据值层面的转义,而表名属于SQL标识符,不能被当作字符串值处理,所以直接用?传表名会触发语法错误。

可行解决方案

  • 白名单校验(最推荐,安全性最高)
    提前在后端枚举所有允许用户访问的表名列表,用户传入的selected_table必须严格匹配白名单内的元素才能执行后续查询,完全杜绝非法表名传入。
    示例逻辑:
    # 替换为实际允许用户访问的表名集合
    ALLOWED_TABLES = {"user_info", "order_record", "product_list"}
    selected_table = selected_table.strip()
    if selected_table not in ALLOWED_TABLES:
        raise PermissionError("访问的表不存在或无权限")
    # 校验通过后再执行查询
    cursor.execute("SELECT * FROM {0} ".format(selected_table))
    
  • 使用数据库驱动自带的标识符转义方法
    绝大多数数据库的Python驱动都提供了专门针对SQL标识符(表名、列名)的转义工具,会自动处理特殊字符、添加规范的标识符包裹符号,避免注入风险。
    不同驱动示例:
    • PostgreSQL(psycopg2):
      from psycopg2 import sql
      cursor.execute(sql.SQL("SELECT * FROM {}").format(sql.Identifier(selected_table)))
      
    • MySQL(PyMySQL):
      escaped_table = connection.escape_string(selected_table)
      cursor.execute(f"SELECT * FROM `{escaped_table}`")
      
    • SQLite:
      escaped_table = conn.quote(selected_table)
      cursor.execute(f"SELECT * FROM {escaped_table}")
      
  • 系统表校验(适合表列表变动频繁的场景)
    先从数据库的系统表中查询当前库下所有合法的用户表名,校验用户传入的表名是否真实存在,再执行查询。比如MySQL可以查询information_schema.TABLES表,PostgreSQL查询pg_tables表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 21:36:07