2017年,入和某电商平台的入和安全工程师在日志里发现一条异常请求——用户ID参数后面跟着一串' OR 1=1 --。这条请求直接拉出了全量用户数据,入和包括密码哈希。入和攻击者没用什么高端工具,入和就靠一个单引号。入和
SQL注入的入和本质,是入和程序把用户输入当成了代码执行。你明明只想要一个用户名,入和它却把你的入和输入拼进SQL语句里。数据库分不清哪部分是入和用户数据,哪部分是入和逻辑指令。就这么简单,入和也这么致命。入和
我见过太多开发者的入和误区,以为只要过滤几个关键字就安全了。他们滤掉select、滤掉union,以为万事大吉。结果攻击者用SeLeCt大小写混写就绕过去了。还有人只防GET请求,POST参数完全裸奔。这就像给前门上了锁,后门却敞开着。
真正有效的办法只有一个:参数化查询。把SQL语句的结构和数据分开,让数据库永远不把用户输入当指令。这跟过滤黑名单完全是两码事。你不需要记住所有攻击payload,只需要保证代码结构不变。可惜,不少老项目改起来麻烦,就继续用拼接字符串,然后祈祷没人发现漏洞。
XSS攻击则是另一路数。它不碰数据库,而是盯上了浏览器。攻击者把脚本塞进页面,让别人的浏览器执行。存储型XSS最阴险——攻击者把恶意代码存到服务器上,每个访问页面的用户都中招。反射型需要诱导用户点击链接,但配合短链接和钓鱼邮件,照样能骗到不少人。
有个案例让我印象很深:某论坛把用户昵称直接渲染到页面上,没做任何转义。攻击者注册了个昵称叫<script>alert(document.cookie)</script>的用户。管理员一登录后台,脚本就执行了,cookie直接被偷走。整个后台沦陷,就因为这个不起眼的昵称字段。
对付XSS,核心原则是"永远不要信任用户输入"。输出到HTML时,按上下文做编码。在标签里就转义尖括号,在属性里就转义引号,在script里就得做JS编码。很多人以为只转义<和>就够了,结果在onclick属性里照样能执行javascript:伪协议。
说实话,这两类攻击都存在二十年了,但每年OWASP Top 10里它们依然榜上有名。为什么?因为根子在人。开发者图省事,写代码时想着"先跑通再说",安全测试靠自动化扫描,扫不出来就当没漏洞。可真正的安全问题,往往藏在业务逻辑的缝隙里。
我见过一个团队,安全整改时把参数化查询全做了,XSS过滤也加了,自认为固若金汤。结果审计发现,他们有个导出Excel的功能,直接把用户输入的公式拼进单元格。Excel打开时执行了外部链接,等于二次注入。这种边角料的问题,自动化工具根本发现不了。
安全不是某个环节的事。从需求分析到代码审查,从测试到运维,每个环节都得绷着根弦。别把希望寄托在WAF或者某个安全组件上——那些只是缓解措施,不是根治方案。真正的防线,是你写每一行代码时,都想着"如果用户输入的是恶意数据,会发生什么"。
说句难听的,很多漏洞不是技术问题,是态度问题。懒,侥幸,觉得"没人会攻击我这个小站"。可攻击者偏偏就喜欢找这种软柿子捏。你的数据库里哪怕只有一条用户记录,也值得被保护。别等到数据泄露了,才后悔当初没多写几行安全的代码。