外观
OWASP Top 10(2025)详解
从攻击者的视角检查应用,再把安全控制落实到设计、编码、交付和运行阶段。
OWASP(Open Worldwide Application Security Project,开放全球应用安全项目)是一个专注于应用安全的开放社区。OWASP Top 10 是其最具代表性的安全意识文档:它总结了 Web 应用中最关键的十类风险,适合作为团队建立安全开发基线的起点。
本文介绍当前正式版本 OWASP Top 10:2025。需要注意,Top 10 是风险分类和教育材料,不是完整的安全标准,也不能代替威胁建模、代码审计或渗透测试。
十类风险速览
| 排名 | 风险 | 一句话理解 |
|---|---|---|
| A01 | 访问控制失效 | 用户能够执行权限之外的操作 |
| A02 | 安全配置错误 | 不安全的默认值、暴露的服务或错误配置形成攻击面 |
| A03 | 软件供应链失效 | 依赖、构建与发布链路被漏洞或篡改影响 |
| A04 | 加密机制失效 | 敏感数据没有被正确加密和保护 |
| A05 | 注入 | 不可信输入被当成命令、查询或代码执行 |
| A06 | 不安全设计 | 系统设计本身缺少必要的安全约束 |
| A07 | 身份认证失效 | 登录、会话和凭据恢复机制可被绕过或滥用 |
| A08 | 软件或数据完整性失效 | 对代码、更新或关键数据的可信假设没有得到验证 |
| A09 | 安全日志与告警失效 | 攻击发生后无法及时发现、追踪和响应 |
| A10 | 异常条件处理不当 | 系统在错误、资源耗尽等异常状态下不再安全 |
A01:访问控制失效(Broken Access Control)
访问控制决定“谁能对什么资源执行什么操作”。认证成功只说明用户是谁,并不意味着用户可以访问任意数据。
典型场景包括:
- 普通用户直接访问管理员接口;
- 修改 URL 中的订单 ID 后读到其他用户的订单,即 IDOR;
- 仅在前端隐藏按钮,后端没有再次检查权限;
- 服务端请求伪造(SSRF)让服务器访问本不应开放的内部资源。
ts
// 错误:只按客户端传入的 id 查询
const invoice = await db.invoice.findUnique({ where: { id: req.params.id } })
// 正确:查询条件同时约束资源归属
const invoice = await db.invoice.findFirst({
where: { id: req.params.id, ownerId: req.user.id }
})**如何防御:**默认拒绝访问;在服务端统一执行授权;对每个对象校验所有权;采用最小权限;限制跨域访问;记录并告警重复的越权尝试。对于服务端出站请求,应使用目标白名单并隔离云元数据与内网地址。
A02:安全配置错误(Security Misconfiguration)
现代应用依赖框架、容器、云服务和大量配置。调试模式未关闭、默认账号未删除、对象存储桶公开、错误页面泄露堆栈,都会让攻击者更容易找到入口。
如何防御:
- 为开发、测试、生产环境建立可重复的加固模板;
- 删除不需要的功能、示例、端口和默认账号;
- 使用安全响应头,如 CSP、
X-Content-Type-Options和合理的 HSTS; - 不向客户端返回堆栈、数据库错误或内部路径;
- 在 CI/CD 中扫描基础设施即代码、容器镜像和云配置漂移。
A03:软件供应链失效(Software Supply Chain Failures)
2025 版把 2021 年的“易受攻击和过时的组件”扩展为整个软件供应链:风险不仅来自有漏洞的依赖,还可能来自被接管的软件包、投毒的构建工具、泄露的发布凭据或不可信的制品仓库。
**如何防御:**维护软件物料清单(SBOM);锁定并审核依赖版本;只从可信源获取软件包;持续进行 SCA 漏洞扫描;保护 CI/CD 凭据和构建节点;对发布制品签名并在部署前验证来源与完整性。删除依赖前也要确认它是否被间接引用,升级则应配合回归测试。
A04:加密机制失效(Cryptographic Failures)
这类问题常导致密码、会话、个人信息或支付数据泄露。例如使用 HTTP 明文传输、把密码可逆加密后存储、使用过时算法,或把密钥直接提交到代码仓库。
ts
// 不要保存明文密码,也不要使用普通哈希(如 SHA-256)直接处理密码
// 应选择成熟库提供的 Argon2id、scrypt 或 bcrypt,并配置合理成本
const passwordHash = await argon2.hash(password, { type: argon2.argon2id })**如何防御:**先进行数据分类,只收集和保存必需的数据;传输使用 TLS;静态敏感数据采用经过验证的现代算法;密码使用专用的慢哈希;密钥放入密钥管理系统并定期轮换;不要自行设计加密算法或协议。
A05:注入(Injection)
当应用把不可信输入拼接到 SQL、NoSQL、操作系统命令、模板或 LDAP 查询中,输入就可能从“数据”变成“指令”。跨站脚本(XSS)也属于这一类别。
ts
// 错误:字符串拼接造成 SQL 注入
db.query(`SELECT * FROM users WHERE email = '${email}'`)
// 正确:使用参数化查询
db.query('SELECT * FROM users WHERE email = ?', [email])**如何防御:**优先使用参数化查询和安全 API;根据业务规则验证输入;输出到 HTML、URL、JavaScript 等不同上下文时分别编码;谨慎使用解释器和 shell;通过 CSP 降低 XSS 的影响。输入过滤是补充手段,不能代替参数化。
A06:不安全设计(Insecure Design)
实现无误不代表设计安全。例如优惠券可以无限叠加、转账没有额度限制、重置密码流程可枚举用户——这些都是业务规则和安全控制在设计阶段的缺失,仅靠扫描器很难发现。
**如何防御:**在开发前完成威胁建模;为高风险业务编写滥用案例;定义信任边界和安全需求;对敏感操作增加限速、二次确认与状态校验;采用分层防御;通过单元测试和集成测试验证安全约束。
A07:身份认证失效(Authentication Failures)
常见问题包括弱密码策略、允许无限次登录尝试、会话 ID 不轮换、退出后令牌仍有效、多因素认证可被绕过,以及不安全的找回密码流程。
**如何防御:**优先使用经过验证的身份平台和标准协议;高风险场景启用抗钓鱼 MFA;检测撞库和凭据填充;登录后轮换会话 ID;Cookie 设置 HttpOnly、Secure 和适当的 SameSite;为会话设置空闲与绝对过期时间;恢复流程不得泄露账号是否存在。
A08:软件或数据完整性失效(Software or Data Integrity Failures)
应用经常默认相信更新、插件、反序列化数据或流水线产物。如果缺少签名和完整性验证,攻击者就可能替换代码或修改数据。它与 A03 有交集,但更强调具体软件、代码和数据制品的信任边界。
**如何防御:**验证更新和制品的数字签名;限制并审查反序列化的数据类型;避免反序列化不可信对象;保护代码仓库和流水线的审批规则;让关键数据变更可审计;外部脚本使用子资源完整性(SRI)或托管可信副本。
A09:安全日志与告警失效(Security Logging and Alerting Failures)
只有日志而没有告警,攻击仍可能长期不被发现。反过来,记录密码、令牌等敏感数据,又会制造新的泄露风险。
**如何防御:**记录登录失败、授权失败、管理操作和关键数据变更;采用统一时间与结构化格式;为日志设置防篡改、访问控制和保留策略;对异常行为设定可执行的告警;定期演练事件响应,并确认从告警到处置的链路真正可用。
A10:异常条件处理不当(Mishandling of Exceptional Conditions)
这是 2025 版新增类别。网络超时、缺少参数、权限不足、资源耗尽和意外状态都可能触发异常。如果系统“失败时放行”(fail open)、只完成一半事务,或把内部错误完整返回给用户,就可能带来绕过、数据破坏和拒绝服务。
ts
try {
await authorizeAndTransfer(command)
} catch (error) {
logger.error({ errorId, userId: user.id }, 'transfer failed')
// 对外返回稳定、最小化的信息;默认拒绝,而不是继续执行
return reply.status(500).send({ error: 'TRANSFER_FAILED', errorId })
}**如何防御:**集中处理异常;默认安全失败;使用事务保证操作原子性;为超时、重试和熔断设置明确边界;限制内存、连接、请求体等资源;返回通用错误信息并保留可关联的错误 ID;测试依赖不可用、部分失败和资源耗尽等故障路径。
从 2021 到 2025,有什么变化?
- 访问控制失效仍位列第一,SSRF 被合并到该类别;
- 安全配置错误从第五升至第二;
- “易受攻击和过时的组件”扩展为更完整的“软件供应链失效”;
- 身份认证类别名称简化,但核心关注点延续;
- 日志类别进一步强调:记录之后必须有告警和响应;
- 新增“异常条件处理不当”,聚焦错误处理、逻辑错误和失败时放行。
团队落地检查清单
可以把 Top 10 转换为交付流程中的可验证活动:
- **设计阶段:**完成威胁建模,列出资产、信任边界、滥用案例和安全需求。
- **编码阶段:**统一使用鉴权、参数化查询、输出编码、密码哈希和异常处理组件。
- **提交阶段:**执行密钥扫描、静态分析、依赖与许可证扫描,保护主分支。
- **构建阶段:**隔离流水线,生成 SBOM,对制品签名并验证来源。
- **测试阶段:**覆盖越权、身份认证、业务逻辑、异常路径和安全配置测试。
- **部署阶段:**执行最小权限,管理密钥,扫描云与容器配置,关闭调试能力。
- **运行阶段:**集中日志、配置有效告警、修补漏洞,并定期演练事件响应。
结语
OWASP Top 10 的价值不在于背下十个名称,而在于建立共同语言:产品人员能在需求阶段识别滥用场景,开发者能写出默认安全的代码,运维人员能控制配置和供应链,安全团队则能持续验证并推动改进。
最好的使用方式,是把每一类风险变成团队自己的设计规则、代码规范、自动化检查和事故演练,而不是上线前才做一次“安全体检”。
参考资料
- OWASP Top 10:2025
- OWASP Top 10:2025 — Introduction
- OWASP Cheat Sheet Series
- OWASP Application Security Verification Standard
本文用于安全教育。示例经过简化,实际项目应结合业务风险、技术栈与合规要求实施控制。
