假设 card_key = "ABC'; DROP TABLE card_keys; --"
sql = f"SELECT ... WHERE card_key = '{card_key}'"
conn.execute(sql)
"
最终生成的 SQL 变成了:
SELECT * FROM card_keys WHERE card_key = 'ABC'; DROP TABLE card_keys; --'
数据库会傻傻地执行两条命令:先查,再把表删了!
使用占位符
conn.execute('SELECT ... WHERE card_key = ?', (card_key,))
加逗号是为了被识别成元组
Python 会告诉数据库:“这是数据,不是代码,请严格按数据处理。”
即便 card_key 里包含了恶意的 SQL 代码(如上面的 DROP TABLE),
数据库也会把它当成“普通的字符串”去查找,而不会去执行它。
为什么要是元组?
execute() 方法非常严格,它要求参数必须是“序列类型”(Sequence)。