知识卡片

SQL注入的根因与解法:参数化查询把数据和代码彻底分离

普通读书笔记卡

内容

SQL注入漏洞的根源在于把用户输入的数据直接拼接进SQL语句的文本里执行——一旦用户输入的内容里恰好包含了SQL语法的关键字或符号(比如’ or 1=1 or “=‘这样的片段),这段本该被当作”纯数据”处理的用户输入,就会被数据库当成SQL语句的一部分来解析执行,轻则让原本只返回单条记录的查询变成返回整张表的所有数据,重则让数据库执行本不该被允许的删除操作,甚至导致数据库服务器本身被入侵。真正解决这个问题的方法不是在拼接之前对用户输入做转义或过滤(这类黑名单式过滤总有被绕过的可能),而是从根本上避免”把数据和SQL代码放在同一段文本里拼接”这件事——改用参数绑定(预编译语句)的方式,先把SQL语句的结构(包括占位符)预先编译好,用户输入的数据只会被当作参数值填入占位符,数据库执行引擎从协议层面就把”这是数据”和”这是SQL代码”区分开,用户输入无论包含什么内容,都不可能被重新解释成SQL语法的一部分。这个案例给出一条对所有类似注入类漏洞(不只是SQL注入)都适用的通用原则:注入类漏洞的根源往往是”数据”和”代码”被混在同一条文本通道里处理,解法不是在这条混合通道上打补丁式地过滤,而是从协议或接口层面把数据和代码彻底分离成两条独立通道。

参考来源

- 位置:《高可用架构(第1卷)》第7章《安全与网络》"7.5 互联网主要安全威胁分析及应对方案"节,"7.5.1 互联网Web应用面临的主要威胁","2.SQL注入"及"7.5.2 威胁应对方案","3.SQL注入"(源文件:_epub-src/OEBPS/Text/Chapter7_5_2.xhtml、Chapter7_5_3.xhtml) - 结论依据:原文说明"如果传入的ID不是预期的普通字符串,而是' or 1=1 or ''='时便会生成如下SQL。这条SQL会返回指定表的所有数据……防范SQL注入的方法比较简单,主要方法是阻止开发人员拼接SQL,使用参数绑定的方式取代",直接支撑本卡片结论。 - 原始内容:如果传入的ID不是预期的普通字符串,而是' or 1=1 or ''='时便会生成如下SQL。这条SQL会返回指定表的所有数据……防范SQL注入的方法比较简单,主要方法是阻止开发人员拼接SQL,使用参数绑定的方式取代。