欢迎访问 内存溢出 —— 独立后端与系统工程技术博客

专注于分布式系统、Linux内核、数据库存储与后端工程实践

深入浅出 SQL 注入防御:AST 语法树重构与预编译原理

发表于:|最后更新:|分类:安全与运维|阅读:6811 次

SQL 注入(SQLi)长期盘踞 OWASP Top 10,其攻击本质在于:数据与代码的边界混淆。当应用将未经严格过滤的用户输入采用字符串拼接的方式组合成 SQL 语句传给数据库时,恶意输入改变了原本 SQL 语句的抽象语法树(AST, Abstract Syntax Tree)结构。例如简单的登录查询拼接:SQLSELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'xxx'; 在词法分析阶段,原定作为常数字符串字面量(Literal)解析的 '1'='1' 被解析器赋予了布尔表达式的操作符(Binary Expression)语义,使整个 WHERE 条件恒真。预编译语句(Prepared Statements / Parameterized Queries)是根除 SQL 注入的唯一黄金解法。其运行机制完全不同于文本替换:预编译阶段:应用将带有占位符(如 ? 或 $1)的 SQL 模板发送给数据库。数据库编译器立即对其进行词法与语法分析,生成固化、不可变的 AST 语法树。执行阶段:应用将用户输入作为纯粹的参数协议二进制流发送。数据库直接将这些数据填入已定型的语法树特定叶子节点。无论用户传入的内容多么诡异(包含单引号、分号、UNION 关键字等),数据库引擎从物理机制上仅将其视作一个不可拆分的字面量值,无法对语法树产生任何拓扑结构的突变,从而在源头上抹杀了注入的可能性。