OWASP Top 10 完全指南:Web 应用最重要的 10 类安全威胁

OWASP Top 10 是 Web 安全的"必读清单",每 3-4 年更新一次,反映当下最严重的应用层安全问题。但很多团队对它的认识停留在"听说过",真到了开发中并没系统防护。这篇文章把 2021 版 OWASP Top 10 完整讲透,所有威胁配真实代码示例和修复方案,2024 年新趋势也会提到。

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

排第一,因为最普遍。本质:用户能访问不该访问的资源

水平越权

# 错:用户能改任意 id 的资源
GET /api/orders/123    # 用户 A 拿自己的订单
GET /api/orders/124    # 改一下 URL,拿用户 B 的订单 —— 也能拿到!

# 修复:每次访问都校验"这资源属于当前用户"
def get_order(order_id):
    order = db.find_order(order_id)
    if order.user_id != current_user.id:
        return forbidden()
    return order

垂直越权

# 错:普通接口里漏了权限校验
POST /api/admin/users/delete    # 后端没检查 role

# 修复:加权限装饰器
@require_role('admin')
def delete_user(...):
    ...

检测方法

每个接口都问:"这个接口能做什么 + 谁应该能做 + 我现在校验了什么"。漏了任何一环就是漏洞。Burp Suite、OWASP ZAP 等工具能自动化测试越权。

A02 Cryptographic Failures(加密失败)

对应旧版的"敏感数据泄露"。涉及:

  • 明文存密码 / 信用卡。
  • 用过时算法(MD5、SHA1、DES、RC4)。
  • 密钥写在代码里。
  • HTTP 传输敏感数据(不走 TLS,在 HTTP 之上加一层 TLS 加密,防止中间人窃听和篡改。">HTTPS)。
# 错:MD5 存密码
password_hash = hashlib.md5(password.encode()).hexdigest()
# MD5 已被破解,撞库工具几秒搞定

# 对:bcrypt / argon2
import bcrypt
hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

# 验证
bcrypt.checkpw(password.encode(), hash)

规则:

  • 密码用 bcrypt / argon2 / scrypt,不要用 SHA 系列。
  • 对称加密用 AES-GCM,不要用 ECB 模式。
  • 非对称用 RSA-OAEP / ECC,不要用 PKCS#1 v1.5。
  • 密钥用 KMS / Vault 管理,绝不进代码仓库。
  • TLS 1.2+ 强制,旧版本(SSLv3 / TLS 1.0 / 1.1)关闭。

A03 Injection(注入)

SQL 注入、NoSQL 注入、命令注入、LDAP 注入、模板注入。本质都是"用户输入被当作代码执行"。

SQL 注入

# 错:字符串拼接
sql = f"SELECT * FROM users WHERE name = '{username}'"
# username = "admin' OR '1'='1"  -> 绕过认证
# username = "x'; DROP TABLE users; --"  -> 直接干掉表

# 对:参数化查询
cursor.execute("SELECT * FROM users WHERE name = ?", (username,))

命令注入

# 错:用户输入拼到 shell
os.system(f"ping {host}")
# host = "google.com; rm -rf /"  -> 删了

# 对:用列表传参,不走 shell
subprocess.run(["ping", "-c", "1", host], shell=False)

NoSQL 注入

# 错:MongoDB 接受用户传 JSON
db.users.find({ "username": req.body.username, "password": req.body.password });
// 攻击者传:{ "username": "admin", "password": { "$ne": null } }
// 等于查"有任何密码的 admin"

// 对:校验输入类型
if (typeof req.body.password !== 'string') return error();

A04 Insecure Design(不安全的设计)

这是 2021 新增的类别,强调"设计阶段的安全缺陷" —— 不是写错代码,而是设计本身就漏了威胁建模。

例子:密码重置只验证邮箱,没有验证旧密码或二步认证 —— 邮箱被劫持就丢账号。修复:多因素认证、Threat Modeling 在设计阶段就识别风险。

A05 Security Misconfiguration(安全配置错误)

  • 用默认密码(admin/admin、root/root)。
  • 错误信息泄露技术栈("Stack Trace 出现在用户页面")。
  • 未禁用调试端点(/actuator 暴露在公网)。
  • 权限配置过宽(S3 bucket public-read 暴露内部数据)。
  • HTTP Header 缺失(没有 Content-Security-Policy、X-Frame-Options)。
# 必备 HTTP 安全头
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; ...
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=()

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

用了有 CVE 的库。修复:

  • 持续扫描依赖:Dependabot、Snyk、Trivy、SCA(Software Composition Analysis)工具。
  • 及时升级:CVE 公开后大概几天就会出现批量扫描的攻击者。
  • 固定版本:lock 文件(package-lock.json、Pipfile.lock)防止隐式升级到坏版本。

2021 年的 Log4Shell(CVE-2021-44228)是这类问题的极致案例 —— 一个 Log4j 库的远程代码执行,影响全球几百万系统,因为这个库几乎装在每个 Java 项目里。

A07 Identification and Authentication Failures(身份认证失败)

  • 密码弱:允许 "123456"、不限制尝试次数。
  • Session 管理差:Session ID 可预测、不绑定 IP、不过期。
  • 没有多因素认证
  • 密码恢复流程脆弱:只发邮件就能重置,且不限制次数。

修复:强密码策略、限流登录尝试(5 次失败锁 15 分钟)、强制 MFA(至少给管理员账号)、Session 适当短(15-60 分钟)、登出主动清 Session。

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

  • 反序列化漏洞:Python pickle、PHP unserialize、Java 反序列化 —— 把用户输入直接反序列化能触发任意代码执行。
  • 不验证更新的完整性:CDN 加载的 JS / 第三方依赖被替换,你的应用执行恶意代码。
  • CI/CD 缺乏完整性:构建脚本被改、镜像被替换。
# JS 加载第三方脚本要校验完整性(SRI)
<script src="https://cdn.example.com/lib.js"
        integrity="sha384-xxx"
        crossorigin="anonymous"></script>
# 浏览器会校验哈希,不匹配就拒绝执行

# 不要反序列化不可信数据
pickle.loads(user_input)         # 危险!
json.loads(user_input)            # 安全,只是数据

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

没记日志 = 出了事查不到。需要记录:

  • 登录尝试(成功 + 失败,带 IP / UA)。
  • 权限变更(谁给谁授了什么权限)。
  • 敏感操作(转账、删除、导出数据)。
  • API 错误(尤其 401/403/500)。

同时要告警:登录失败激增 / 权限授予异常 / 错误率飙升 → 立刻通知安全团队。

A10 Server-Side Request Forgery (SSRF)

服务器收到用户输入的 URL,主动去访问 —— 如果 URL 是内网地址或云元数据接口,就泄露了内部信息。

# 错:用户输入图片 URL,服务端 download
@app.route('/download')
def download():
    url = request.args.get('url')
    response = requests.get(url)
    return response.content

# 攻击:url = http://169.254.169.254/latest/meta-data/iam/security-credentials/
# AWS / 阿里云 / GCP 都有这个内网元数据接口,返回临时密钥!

# 修复:URL 白名单 / 禁止访问内网 / 校验响应 IP
import ipaddress
def is_safe_url(url):
    host = urlparse(url).hostname
    ip = socket.gethostbyname(host)
    addr = ipaddress.ip_address(ip)
    return not (addr.is_private or addr.is_loopback or addr.is_link_local)

SSRF 在云时代尤其危险 —— 元数据接口里的临时凭证一旦泄漏,攻击者能用它访问云资源(读 S3、改 IAM 角色、起 EC2)。所有"服务端代理用户 URL"的接口必须严格白名单。

2024 年的新威胁趋势

  • AI / LLM 安全:Prompt Injection、训练数据投毒、模型泄露。OWASP 已经出了"OWASP Top 10 for LLM Applications"。
  • 供应链攻击:不是攻击你的代码,而是攻击你的依赖、构建工具、CI/CD。SolarWinds、xz-utils 后门都是这类。
  • API 暴露:微服务时代 API 数量爆炸,文档化 / 访问控制 / 限流跟不上。

实战:把安全做进开发流程

  1. SAST(静态代码扫描):SonarQube、Semgrep。每次 PR 跑。
  2. SCA(依赖扫描):Snyk、Dependabot。监控 CVE。
  3. DAST(动态扫描):OWASP ZAP、Burp Suite。预发环境定期跑。
  4. Threat Modeling:每个新功能设计阶段做"STRIDE"分析。
  5. Pentest:每年一次外部渗透测试。
  6. Bug Bounty:让白帽子帮你找漏洞,有偿。

XSS 跨站脚本攻击详解

XSS 不在 2021 OWASP Top 10 单独列出(归入 Injection),但仍然是 Web 最常见的攻击之一。三种类型:

1. 反射型 XSS

# 用户被诱导点击恶意链接:
https://app.com/search?q=<script>steal_cookie()</script>

# 后端把 q 直接拼进 HTML:
<p>搜索结果:</p> -> <p>搜索结果:<script>...</script></p>
# 浏览器执行了脚本

2. 存储型 XSS

用户评论里包含 <script>,被存到数据库,其他用户看评论时执行。比反射型危害大。

3. DOM 型 XSS

// 前端直接用 URL 参数渲染
document.getElementById('greet').innerHTML = location.hash.slice(1);
// hash = "#<img src=x onerror=alert(1)>"  -> XSS

防御

  • 输出转义:所有从用户输入来的内容,渲染到 HTML 时用 htmlspecialchars / escape
  • 禁用 innerHTML:用 textContent 或框架内置(React 的 JSX 自动转义)。
  • CSP:Content-Security-Policy 头限制 inline script 和外部脚本来源。script-src 'self' 强制脚本只能从自己域名加载,即使 XSS 注入也跑不起来。
  • HttpOnly Cookie:登录 cookie 设 HttpOnly,XSS 偷不走。

CSRF 跨站请求伪造

用户在 A 网站登录,B 网站构造一个请求让用户提交,浏览器会带上 A 的 cookie:

# B 网站的页面:
<img src="https://bank.com/transfer?to=hacker&amount=1000">
# 用户访问 B 时,浏览器自动带 bank.com 的 cookie 发请求 -> 钱被转

防御

  • SameSite Cookie:Set-Cookie 加 SameSite=Lax 或 Strict,第三方网站发请求不带 cookie。现代浏览器默认 Lax。
  • CSRF Token:服务端生成随机 token 放表单,提交时校验。攻击者不知道 token,无法构造合法请求。
  • 检查 Origin / Referer:只接受同源请求。

速率限制是安全防护

暴力破解、密码喷洒、API 滥用 —— 都靠速率限制兜底:

# 登录接口:
- 同一 IP 每分钟最多 5 次失败
- 同一账号每小时最多 10 次失败
- 失败超阈值锁账号 15 分钟 + 发邮件提醒

没有速率限制的登录接口,攻击者一天能跑几百万次密码尝试。

密钥管理

所有密码 / API Key / JWT secret / 数据库密码 都不能进代码仓库。常见方案:

  • 环境变量:简单,但容器编排时仍要从某处来。
  • HashiCorp Vault:专业密钥管理,支持动态密钥、自动轮换。
  • 云厂商 KMS:AWS Secrets Manager、阿里云 KMS、GCP Secret Manager。
  • Kubernetes Secrets + Sealed Secrets:K8s 环境的标配。

关键操作:定期轮换(每季度 / 半年)、泄漏立刻吊销限制访问权限(只让需要的服务能读)。

写在最后

OWASP Top 10 不是 checklist,是"思考框架"。每写一段代码,问自己:"这里可能被注入吗?访问控制对吗?加密强吗?日志够吗?" 把这种思考变成习惯,你写的代码自然不容易出安全洞。

给一个职业建议:每个工程师都该学一遍 OWASP Top 10。不是为了变成安全工程师,而是因为大多数严重的线上安全事故都是普通工程师写出来的普通 bug。安全团队不可能 review 每行代码,但每个写代码的人能识别"这里有 SQL 注入"或"这里漏权限",事故率就会大幅下降。这是性价比最高的安全投资。

一图看懂

OWASP Top 10 一图看懂:

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

JWT 完全指南:从结构到 RS256 与 Refresh Token 的生产实战

2026-5-15 17:25:46

技术教程

密码哈希完全指南:从 bcrypt 到 Argon2 的现代选型

2026-5-15 17:32:37

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索