游客发表
一个登录框,透教输入 ' OR 1=1 -- ,透教回车。透教如果运气好,透教你就进去了。透教这不是透教电影情节,是透教我第一次在测试环境里亲手干成的事。那一刻我意识到,透教所谓“安全漏洞”,透教有时候就是透教一行没过滤的字符串。
SQL注入的透教本质,是透教把你的输入变成SQL代码的一部分。开发者写 SELECT * FROM users WHERE name='$input',透教你传进去一个 ' OR 1=1 --,透教语句就变成了 SELECT * FROM users WHERE name='' OR 1=1 -- '。透教两个连字符把后面的单引号注释掉,条件恒真,整个表都吐出来。就这么简单,不涉及什么高深数学,纯粹是字符串拼接没设防。
真实案例比教科书狠多了。2017年Equifax泄露1.4亿美国人的社保号,官方后来承认是Apache Struts的一个已知漏洞没打补丁,攻击者用的就是SQL注入变种。还有更早的2008年,一个叫“Ruskoff”的黑客用SQL注入把美国军方数据库掀了个底朝天,五角大楼的官员在听证会上脸都绿了。你以为这些攻击者多聪明?他们大多只是拿现成的sqlmap工具扫一遍,工具自动跑,命中就收工。
防御手段说穿了也就三板斧。第一,参数化查询,这是最硬的盾。PHP里写 PDO::prepare(),Java里用 PreparedStatement,让数据库把输入当数据而不是代码来解析。第二,严格校验输入类型,数字就只允许数字,字符串就限制长度和字符集,别图省事一股脑全收。第三,给数据库账号最小权限,就算被注入了,攻击者也只能摸到一张表,而不是整个服务器。
我见过最离谱的防御失败案例,是某公司把用户输入直接拼进存储过程,还在代码注释里写着“这里已做安全处理”。我顺着注释往上翻,发现所谓“安全处理”就是replace掉“select”和“union”这两个词。攻击者输入 SeLeCt 混合大小写就绕过去了。这种自作聪明的过滤,比不防还危险,因为它给你一种虚假的安全感。
还有个细节很多人忽略——错误信息。默认的数据库报错会把SQL语句片段直接吐回浏览器,等于给攻击者递地图。生产环境里必须把错误信息关掉,换成统一的“服务器繁忙”页面。我见过某电商网站,输入一个单引号就报出完整的SQL语句,连表名和字段名都清清楚楚。这等于把保险柜密码写在柜门上。
说实话,SQL注入这玩意儿从1998年被公开提出到现在二十多年了,OWASP Top 10里年年上榜,可每年还是有大厂中招。为什么?因为写代码的人换了一茬又一茬,新人刚学会 SELECT 就直接拼字符串,没人告诉他们这有什么问题。安全培训的PPT做得再精美,不如让新人亲手打一次靶场,被注入一次,疼一次,就记住了。
最后说点实操的。你手上有个旧系统,代码烂得没法重构,那就加个Web应用防火墙(WAF)挡在前面,规则里把常见的注入模式拦掉。虽然WAF能被绕过,但至少拦住八成的脚本小子。更狠一点的做法是,把数据库账号设成只读权限,业务上不需要写的操作全部只读,注入进去也只能看不能改,损失降到最低。
记住,SQL注入不是一道数学题,而是一道习惯题。你每次写SQL都问自己一句:“这个输入如果是恶意构造的,我的代码会怎么死?” 想明白了,你就不会死。想不明白,数据库迟早给你上一课。
友情链接