OWASP Top 10 是 Web 应用安全领域最权威的参考标准。最新的 2025 版(相对于 2021 版)反映了现代开发环境(如微服务、云原生、AI 辅助开发)中风险重心的转移。
2025 版的三大显著变化
与 2021 版相比,2025 版不仅是排名的变动,更引入了全新的安全视角:
- 新增:A03 软件供应链失败 (Software Supply Chain Failures) 这是本次更新最值得关注的点。它从原有的“使用含有已知漏洞的组件”大幅扩张。现在,你不仅要关心库是否有漏洞,还要关心你的构建管道(CI/CD)、私有仓库以及第三方依赖的完整性。对于 Node.js (npm) 和 Java (Maven) 开发者来说,防范恶意包劫持是重中之重。
- 新增:A10 异常处理不当 (Mishandling of Exceptional Conditions) 这取代了之前的某些分类,专门强调程序在出错时的表现。例如:详细的错误堆栈泄露敏感信息,或者系统在发生异常时直接“崩溃进入开放状态”(Fail Open),导致绕过安全检查。
- 合并:SSRF(服务端请求伪造)归入 A01 破坏访问控制 OWASP 认为 SSRF 本质上是访问控制的失效——程序允许了本不该发生的跨区请求。
详细内容
A01: 破坏访问控制 (Broken Access Control)
核心定义: 用户能够访问其权限范围之外的数据或功能。这是最常见的漏洞,通常源于代码逻辑错误。
- 攻击场景: 修改 URL 中的参数(如将
host/api/user/101改为/102)就能看到其他人的隐私。 - 开发者对策:
- 不要信任前端传参: 在 Java 后端通过
SecurityContextHolder获取当前登录用户的 ID,而不是从 Request Param 中读取。- 默认拒绝: 除非明确允许,否则所有接口默认需要授权。
- 不要信任前端传参: 在 Java 后端通过
A02: 安全配置错误 (Security Misconfiguration)
核心定义: 系统组件(服务器、数据库、云服务、框架)使用了不安全的默认设置或多余的功能。
- 攻击场景: Spring Boot 应用开启了
Actuator端点且未加防护,导致泄露环境变量(含数据库密码)。 - 开发者对策:
- 关闭所有生产环境不需要的端点和功能。
- 更改所有默认密码。
- 使用
Content-Security-Policy(CSP) 等安全响应头。
A03: 软件供应链失败 (Software Supply Chain Failures) [2025 新增/扩充]
核心定义: 风险不仅在于代码,更在于你依赖的库、构建工具和分发渠道。
- 攻击场景: 一个常用的 npm 或 Maven 插件被黑客接管并注入了恶意代码,在你执行
mvn build时窃取密钥。 - 开发者对策:
- 依赖扫描: 使用
Snyk或OWASP Dependency-Check扫描 Java 项目中的pom.xml。 - 锁定版本: 避免使用
LATEST或范围版本,确保构建产物的一致性。
- 依赖扫描: 使用
A04: 加密失败 (Cryptographic Failures)
核心定义: 敏感数据(密码、健康信息、信用卡)在传输或存储时未得到充分保护。
- 攻击场景: 使用了 MD5 这种已被破解的算法存储密码,或者在配置文件中硬编码了加密密钥。
- 开发者对策:
- 密码加盐哈希: 在 Java 中推荐使用
BCrypt或Argon2。 - 密钥管理: 使用环境变量或 Vault 等密钥管理工具,严禁将 Key 提交到 Git。
- 密码加盐哈希: 在 Java 中推荐使用
A05: 注入 (Injection)
核心定义: 不受信任的数据作为命令或查询的一部分发送给解释器,导致执行非法命令。
- 攻击场景: SQL 注入(通过
' OR 1=1 --绕过登录)或 XSS 注入(在留言板插入恶意 JS 脚本)。 - 开发者对策:
- 参数化查询: 永远不要手动拼接 SQL 字符串,使用 MyBatis 的
#{}或 JPA 的参数化查询。 - 输入验证: 遵循“白名单”校验原则。
- 参数化查询: 永远不要手动拼接 SQL 字符串,使用 MyBatis 的
A06: 不安全的设计 (Insecure Design)
核心定义: 这不是代码实现的问题,而是“架构设计”从根上就错了。
- 攻击场景: 找回密码功能只需输入邮箱,且密保问题过于简单(如“你的出生地”),黑客可以通过暴力破解或社工绕过。
- 开发者对策:
- 安全左移: 在设计文档阶段进行“威胁建模”。
- 异常流量限制: 针对关键业务(支付、重置密码)强制加入速率限制(Rate Limiting)。
A07: 身份验证失败 (Authentication Failures)
核心定义: 确认用户身份的过程存在漏洞。
- 攻击场景: 允许简单的弱密码,或者没有防范暴力破解(Credential Stuffing),导致用户账号被洗。
- 开发者对策:
- 多因素认证 (MFA): 尽可能要求 MFA。
- 会话管理: 确保 Session ID 在登录后重新生成,并设置合理的
Max-Age和HttpOnly标志。
A08: 软件和数据完整性失败
核心定义: 信任了未经校验的软件更新或反序列化对象。
- 攻击场景: Java 的不安全反序列化——攻击者发送一个精心构造的序列化对象,在服务器执行
readObject()时触发远程代码执行 (RCE)。 - 开发者对策:
- 签名校验: 确保自动更新包有数字签名。
- 反序列化白名单: 限制 Java 反序列化时允许实例化的类。
A09: 安全日志和监控失败
核心定义: 攻击发生了,但你没记录,或者记录了没人看,导致攻击者长期潜伏。
- 攻击场景: 黑客在几个月内尝试了数万次密码尝试,但系统日志没有报警,直到数据被拖库才被发现。
- 开发者对策:
- 记录关键操作: 登录失败、权限变更、高额交易必须记录。
- 日志外发: 将日志实时推送到专门的日志分析系统(如 ELK),防止攻击者本地抹除记录。
A10: 异常处理不当 (Mishandling of Exceptional Conditions) [2025 新增]
核心定义: 系统在遇到错误时的反应泄露了信息,或者进入了不安全的状态。
- 攻击场景: Java 后端报错抛出 500 页面,直接把数据库表名、字段名和代码逻辑显示在前端(Stack Trace)。
- 开发者对策:
- 失败闭锁 (Fail-Closed): 如果权限校验服务超时或报错,系统应默认拒绝访问,而不是因为“报错了”就直接放行。
- 全局异常处理: 在 Spring Boot 中使用
@ControllerAdvice统一捕获异常,只给前端返回模糊的错误码。