SQL 注入的根源在于数据与代码边界被打破。当用户输入被拼接进 SQL 字符串时,恶意内容会改变数据库解析器生成的抽象语法树(AST)。
一、危险的字符串拼接
python
# 危险写法:输入 `' OR '1'='1` 可绕过认证
query = f"SELECT * FROM users WHERE name = '{username}'"在词法分析阶段,攻击者注入的引号使原本的字面量提前闭合,后续片段被解析为布尔表达式,导致 WHERE 条件恒真。
二、预编译语句的防御本质
python
cursor.execute("SELECT * FROM users WHERE name = %s", (username,))预编译阶段数据库已将 SQL 模板编译为固定 AST,执行阶段用户输入仅作为纯数据填入叶子节点,无法改变语法树拓扑结构,从根本上消除注入可能。