跳到主要内容

OWASP Top 10 详解

OWASP(开放式 Web 应用安全项目)Top 10 是 Web 应用安全领域最具影响力的标准之一。它总结了最常见、最危险的 Web 安全漏洞,每隔几年更新一次。本章将详细介绍 2021 年版本的 OWASP Top 10。

什么是 OWASP Top 10?

OWASP Top 10 是由 OWASP 社区通过收集和分析全球范围内的 Web 安全漏洞数据,整理出的最常见的十种安全风险。这个列表:

  1. 广泛认可 - 被全球开发者、安全工程师和企业采用
  2. 持续更新 - 每几年根据最新的漏洞数据更新一次
  3. 权威指导 - 成为安全测试和开发的标准参考

OWASP Top 10 2021

以下是 2021 年版本的 OWASP Top 10:

A01:2021 - 失效的访问控制(Broken Access Control)

访问控制决定了用户可以访问哪些资源。失效的访问控制是指用户能够越权访问未经授权的数据或功能。

常见问题

  • 未验证用户身份就允许访问
  • 允许通过修改 URL 参数访问其他用户的数据
  • 没有正确实施访问控制规则
  • 允许查看或修改其他用户的记录

防护措施

  • 对每个资源访问进行身份验证和授权检查
  • 默认拒绝所有访问,只有明确允许的才放行
  • 实施一致的访问控制机制
  • 记录访问控制失败并提醒管理员

示例

// 不安全:直接使用用户输入的 ID
User user = userDao.findById(request.getParameter("id"));

// 安全:验证当前用户有权访问
User currentUser = getCurrentUser();
User user = userDao.findById(request.getParameter("id"));
if (!user.getId().equals(currentUser.getId()) && !currentUser.isAdmin()) {
throw new AccessDeniedException();
}

A02:2021 - 加密失败(Cryptographic Failures)

过去称为"敏感数据泄露",主要关注密码学相关的安全问题。

常见问题

  • 明文传输敏感数据
  • 使用弱加密算法或过时的加密方法
  • 未对敏感数据进行加密
  • 使用默认的加密密钥
  • 不验证证书有效性

防护措施

  • 对所有敏感数据加密存储和传输
  • 使用现代加密算法(如 AES-256、RSA-4096)
  • 禁用弱协议(SSLv3、TLS 1.0/1.1)
  • 正确管理加密密钥
  • 实施 HTTP Strict Transport Security(HSTS)

示例

// 不安全:使用弱加密
Cipher cipher = Cipher.getInstance("DES");

// 安全:使用强加密算法
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// GCM 模式提供认证加密,安全性更高

A03:2021 - 注入(Injection)

注入漏洞发生在用户输入被当作代码执行时。常见的包括 SQL 注入、命令注入、LDAP 注入等。

常见问题

  • 未验证或未清理用户输入
  • 使用字符串拼接构建查询
  • ORM 查询使用未经验证的输入

防护措施

  • 使用参数化查询(预处理语句)
  • 使用 ORM 的参数化功能
  • 限制输入长度和格式
  • 使用白名单验证

示例

// 不安全:SQL 拼接
String query = "SELECT * FROM users WHERE username = '" + username + "'";

// 安全:参数化查询
PreparedStatement stmt = connection.prepareStatement(
"SELECT * FROM users WHERE username = ?"
);
stmt.setString(1, username);

A04:2021 - 不安全设计(Insecure Design)

这是一个新的类别,强调设计层面的安全问题,而不是代码实现问题。

常见问题

  • 缺少安全架构和设计
  • 没有考虑威胁模型
  • 缺乏安全用例和滥用案例分析
  • 不安全的模式被重复使用

防护措施

  • 在开发初期进行威胁建模
  • 实施安全设计模式
  • 分离租户和数据
  • 限制用户资源消耗
  • 从设计上考虑安全性

示例

安全设计原则:
1. 纵深防御 - 多层安全措施
2. 最小权限 - 只授予必要权限
3. 默认安全 - 默认配置应安全
4. 失败安全 - 异常时默认拒绝
5. 开放设计 - 不依赖代码保密

A05:2021 - 安全错误配置(Security Misconfiguration)

最常见的问题是系统或应用的安全配置不当。

常见问题

  • 使用默认配置
  • 开启不必要的功能
  • 错误配置 HTTP 头
  • 详细错误信息泄露敏感信息
  • 使用过时或有漏洞的组件

防护措施

  • 定期审查和更新配置
  • 禁用不必要的功能
  • 实施安全响应头
  • 统一错误处理
  • 自动化配置检查

示例

// 安全响应头配置
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-Frame-Options", "DENY");
response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("Content-Security-Policy", "default-src 'self'");
response.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");

A06:2021 - 易受攻击和过时的组件(Vulnerable and Outdated Components)

使用已知存在漏洞的组件是常见的问题。

常见问题

  • 使用过时或有漏洞的开源库
  • 不及时更新依赖
  • 不评估供应商的安全性
  • 不修复平台漏洞

防护措施

  • 定期更新组件
  • 监控漏洞数据库
  • 使用依赖扫描工具
  • 只使用官方支持的组件
  • 移除不使用的依赖

工具

  • OWASP Dependency-Check
  • Snyk
  • npm audit
  • Renovate

A07:2021 - 识别和身份验证失败(Identification and Authentication Failures)

身份验证和会话管理不当会导致账户被劫持。

常见问题

  • 允许暴力破解
  • 密码强度要求低
  • 暴露用户 ID 或会话 ID
  • 会话 ID 在 URL 中
  • 不安全的会话管理

防护措施

  • 实施账户锁定和验证码
  • 使用强密码策略
  • 使用安全的会话管理
  • 多因素认证
  • 限制会话超时

示例

// 安全会话配置
request.getSession().setMaxInactiveInterval(30 * 60); // 30分钟
Cookie cookie = new Cookie("SESSIONID", sessionId);
cookie.setHttpOnly(true);
cookie.setSecure(true);
cookie.setSameSite("Strict");
response.addCookie(cookie);

A08:2021 - 软件和数据完整性失败(Software and Data Integrity Failures)

代码和基础设施不依赖未经验证的来源会导致完整性问题。

常见问题

  • 不验证 CI/CD 管道的完整性
  • 不安全的反序列化
  • 使用不安全的来源下载依赖
  • 自动更新而不验证

防护措施

  • 签名验证
  • 使用安全的反序列化方法
  • 验证依赖来源
  • 审查代码和配置变更

A09:2021 - 安全日志和监控失败(Security Logging and Monitoring Failures)

没有足够的日志和监控会导致无法检测到攻击。

常见问题

  • 不记录安全相关事件
  • 日志不包含足够的上下文
  • 日志存储不足
  • 没有自动化监控

防护措施

  • 记录所有登录、访问控制失败
  • 确保日志包含足够的上下文
  • 建立监控和告警机制
  • 实施事件响应计划

A10:2021 - 服务器端请求伪造(Server-Side Request Forgery, SSRF)

应用获取用户提供的 URL 时可能被利用发起恶意请求。

常见问题

  • 从用户输入获取 URL
  • 不验证目标 URL
  • 不限制可访问的网络

防护措施

  • 验证用户提供的 URL
  • 禁用 HTTP 重定向
  • 限制可访问的网络范围
  • 使用安全库验证 URL

示例

// 不安全
URL url = new URL(userInput);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

// 安全:验证和限制
URL url = new URL(userInput);
if (!allowedDomains.contains(url.getHost())) {
throw new SecurityException("Domain not allowed");
}

漏洞统计与趋势

根据 OWASP 的统计数据,以下是值得关注的变化:

  1. 访问控制连续多年位居榜首 - 表明授权问题仍是最大的挑战
  2. 注入漏洞仍然普遍 - 虽然防护知识已经很成熟,但仍然经常出现
  3. 组件安全越来越重要 - 现代应用依赖大量第三方组件
  4. 安全设计成为新类别 - 表明整个行业需要更重视设计阶段的安全性

防护策略

针对 OWASP Top 10,建议采用以下整体策略:

1. 安全开发生命周期(SDL)

将安全实践融入整个开发过程:

  • 需求阶段:安全需求分析
  • 设计阶段:威胁建模、安全设计
  • 开发阶段:安全编码规范
  • 测试阶段:安全测试
  • 部署阶段:安全配置

2. 安全自动化

使用自动化工具提高效率:

  • 静态应用安全测试(SAST)
  • 动态应用安全测试(DAST)
  • 软件组成分析(SCA)
  • 交互式应用安全测试(IAST)

3. 持续学习

  • 关注安全社区动态
  • 学习最新的漏洞和防护方法
  • 参加安全培训
  • 获取安全认证

验证与测试

可以使用以下方法验证防护措施:

  1. 代码审查 - 检查是否有安全漏洞
  2. 自动化扫描 - 使用 SAST/DAST 工具
  3. 渗透测试 - 模拟真实攻击
  4. 红蓝对抗 - 团队对抗演练

小结

OWASP Top 10 总结了 Web 应用最常见的安全风险:

  1. 失效的访问控制 - 未正确限制用户访问
  2. 加密失败 - 敏感数据未得到适当保护
  3. 注入 - 用户输入被当作代码执行
  4. 不安全设计 - 设计层面缺少安全考虑
  5. 安全错误配置 - 系统配置不当
  6. 易受攻击的组件 - 使用有漏洞的库
  7. 身份验证失败 - 身份管理不当
  8. 数据完整性失败 - 未验证数据来源
  9. 日志监控不足 - 缺少安全事件记录
  10. 服务器端请求伪造 - URL 验证不足

理解这些漏洞并采取相应的防护措施是构建安全 Web 应用的基础。在后续章节中,我们将详细讨论每种漏洞的原理和防护方法。

练习

  1. 回顾你最近开发的 Web 应用,看看是否存在上述漏洞
  2. 使用自动化工具(如 OWASP ZAP)扫描一个测试应用
  3. 学习一种安全开发方法论(如 Microsoft SDL)