能否将SQLite表名以字符串格式传入?这类写法有什么SQL注入风险
问题解答
1. 是否可以将SQLite表名以字符串格式传入查询语句?
可以实现,但要注意:SQLite的参数化查询占位符(?)仅支持传入查询值,不支持传入表名、列名这类SQL标识符,所以你目前用字符串格式化拼接表名的写法是能跑通功能的,但存在SQL注入风险,对应你第二个问题的隐患。
2. 该写法的SQL注入安全隐患
你现在的写法直接把db_table变量拼进SQL语句,只要db_table的取值有被用户控制的可能,攻击者就可以构造恶意的db_table值篡改SQL逻辑,典型危害包括:
- 删表/篡改数据:比如攻击者构造
db_table = "user_table; DROP TABLE sensitive_table; --",拼接后最终执行的SQL会变成:
后面的查询条件会被SELECT count(user_id) FROM user_table; DROP TABLE sensitive_table; -- WHERE document_id=?--注释掉,直接执行恶意的删表语句。 - 窃取敏感数据:比如攻击者构造
db_table = "user_table UNION SELECT password FROM admin_table --",可以直接把管理员表的密码字段数据和正常查询结果一并返回,造成数据泄露。
安全修复方案
不要直接使用外部传入的表名字符串,提前做白名单校验:
- 先定义所有允许被查询的表名列表
- 每次执行查询前校验传入的
db_table是否在白名单内,不在则直接拒绝执行
示例代码:
# 提前定义允许查询的表白名单 ALLOWED_TABLES = {"user_document", "team_document", "system_log"} with connection as con: if db_table not in ALLOWED_TABLES: raise ValueError("非法的查询表名") # 校验通过后再拼接SQL cur.execute("SELECT count(user_id) FROM {} WHERE document_id=?".format(db_table), (document_id,))
内容的提问来源于stack exchange,提问作者stoic_buddha7
相关产品推荐
相关产品推荐

