当前位置:首页 > 焦点

存在SQL注入漏洞

去年某省医保系统的注入一次例行渗透测试里,安全工程师只用了两个单引号就拿到了管理员权限。漏洞输入框里敲入 ' OR '1'='1,注入登录页面直接跳转到了后台首页。漏洞这不是注入电影桥段,是漏洞真实发生的案例,漏洞点就在登录接口的注入SQL查询语句上。

SQL注入的漏洞本质很简单:应用程序把用户输入的数据当成了SQL代码来执行。比如登录验证的注入代码写成 SELECT * FROM users WHERE username = '$user' AND password = '$pass',当你输入的漏洞用户名是 admin' --,后面的注入密码验证就被注释掉了,数据库只检查用户名是漏洞否存在,密码形同虚设。注入

很多人以为参数化查询已经普及了,漏洞注入漏洞该绝迹了。注入现实是,我翻过近两年的漏洞报告,SQL注入依然排在OWASP Top 10的前三名。为什么?老旧系统改不动,开发人员图省事拼接字符串,ORM框架用错了地方——比如在MyBatis里写 ${ } 而不是 #{ },照样中招。一个做金融的朋友告诉我,他们内部代码审计时发现,超过四成的DAO层方法存在拼接SQL的情况,有些还是核心交易模块。

注入的危害远不止登录绕过。攻击者可以通过联合查询把数据库里的表名、列名、用户密码全部拖出来。更狠的是,如果数据库权限够大,还能写入webshell或者执行系统命令。2019年那个某酒店集团的数据泄露,5亿条开房记录被脱裤,源头就是一个小程序接口的SQL注入。攻击者用sqlmap跑了一晚上,从information_schema开始,一步步拿到所有数据。

怎么判断一个系统有没有注入?手工测试其实不复杂。找一个带参数的URL,比如 ?id=1,在后面加个单引号,页面报错或者返回异常,基本就有戏。再试试 and 1=1 和 and 1=2,如果两次返回结果不同,说明注入点存在。当然,现在很多WAF会拦截,但绕过手法也层出不穷,大小写混写、内联注释、编码变形,总有一款能过。

防御这件事,说来说去就那几条,但真要做到位不容易。参数化查询是根本,所有数据库操作都用预编译语句,别自己拼字符串。输入验证要有,但别指望它挡住一切,白名单比黑名单靠谱。数据库账号权限最小化,别用sa或者root连业务库。WAF可以加,但别当成唯一防线。我见过一个团队,代码里全是拼接,就靠WAF撑着,结果WAF规则一更新,漏网之鱼全出来了。

还有个容易被忽略的点:报错信息别直接返回给前端。数据库的详细错误能帮攻击者省不少事,什么版本、什么表名、什么字段,全暴露了。统一返回“系统繁忙”就行,日志里记详细点,但别让用户看到。

最后说个真实场景。某电商大促前夜,安全团队扫出一个注入点,在商品搜索接口。开发觉得搜索接口不重要,没数据。结果攻击者通过注入拿到了数据库的当前用户,发现是db_owner,然后提权到sysadmin,整个服务器沦陷。大促当天首页被挂马,损失七位数。一个单引号引发的血案,一点都不夸张。

分享到: