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

如何在Python中安全地向SQLite PRAGMA语句传递参数?

解决SQLCipher密钥设置的SQL注入问题

核心问题

直接拼接用户输入的密码到PRAGMA key语句中确实存在SQL注入风险,虽然sqlcipher3的execute方法默认限制单语句执行,能挡住多语句注入,但仍有潜在隐患(比如密钥被意外截断、语法错误导致密钥失效),且常规的参数化绑定对PRAGMA语句不生效。

可行解决方案

方案1:连接时直接指定密钥(推荐)

sqlcipher3的connect方法支持直接传入key参数,无需手动执行PRAGMA语句,从根源避免字符串拼接问题:

from getpass import getpass
import sqlcipher3

password = getpass('Password: ')
# 连接阶段直接传递密钥,底层安全处理
con = sqlcipher3.connect(':memory:', key=password)
cur = con.cursor()

# 后续正常执行数据库操作

这个方法由库底层负责密钥的传递逻辑,完全规避SQL注入风险,是最安全高效的方式。

方案2:手动转义单引号后拼接

如果必须通过PRAGMA语句设置密钥,需要对密码中的单引号按SQL标准转义(用两个单引号表示一个单引号),再拼接语句:

from getpass import getpass
import sqlcipher3

con = sqlcipher3.connect(':memory:')
cur = con.cursor()
password = getpass('Password: ')
# 转义密码中的单引号,避免破坏SQL语法结构
escaped_password = password.replace("'", "''")
cur.execute(f"PRAGMA key='{escaped_password}';")

转义后,即使用户输入hunter2'; DROP TABLE secrets;--,拼接后的语句会变成:

PRAGMA key='hunter2''; DROP TABLE secrets;--';

此时整个字符串会被当作密钥的一部分,不会被解析为额外的SQL语句,既不会执行恶意操作,也能正确设置密钥。

为什么参数化绑定失效

SQLite的参数化占位符仅支持数据操作语言(DML)语句(如INSERT、SELECT、UPDATE),而PRAGMA属于SQL的控制类指令,不支持参数绑定机制,因此使用?或命名占位符会触发语法错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 07:49:58