引言:安全不是功能,而是基础
根据 OWASP Top 10 2021 和 GitHub Security Lab 数据,超过 80% 的 Web 应用存在至少一类高危漏洞。而多数漏洞源于对输入、输出、权限和信任边界的错误假设。
本文将 Web 安全问题划分为 7 大核心类别,每类包含:
- 漏洞原理
- 攻击示例(使用
https://example.com作为目标) - 危害等级
- 防御方案(含代码)
帮助你构建系统性安全认知,写出更健壮的代码。
分类一:注入类漏洞(Injection)
🎯 典型代表:SQL 注入、命令注入、NoSQL 注入
🔍 原理
当应用将用户输入直接拼接到解释型语句(如 SQL、Shell 命令)中,攻击者可构造恶意输入改变语义。
💥 示例(SQL 注入)
GET /user?id=1' OR '1'='1 HTTP/1.1
Host: example.com
后端代码(危险写法):
# ❌ 危险!直接拼接
query = f"SELECT * FROM users WHERE id = '{user_id}'"
→ 实际执行:SELECT * FROM users WHERE id = '1' OR '1'='1' → 返回所有用户!
⚠️ 危害
- 数据泄露、篡改、删除
- 服务器被完全控制(通过
xp_cmdshell等)
✅ 防御
- 使用参数化查询(Prepared Statements)
# ✅ 安全
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
- 输入验证 + 白名单过滤
- 最小权限原则:数据库账号仅授予必要权限
分类二:跨站脚本(XSS, Cross-Site Scripting)
🎯 类型:存储型、反射型、DOM 型
🔍 原理
应用未对用户输入进行转义,直接将其插入 HTML/JS 上下文,导致攻击者脚本在受害者浏览器执行。
💥 示例(反射型 XSS)
GET /search?q=<script>alert(document.cookie)</script> HTTP/1.1
Host: example.com
前端代码(危险):
<!-- ❌ 直接输出 -->
<div>搜索结果: <%= query %></div>
⚠️ 危害
- 窃取 Cookie、Session
- 劫持用户操作(如转账、发消息)
- 蠕虫传播(如 Samy 蠕虫)
✅ 防御
- 输出编码(Output Encoding)
- HTML 上下文:
<→< - JS 上下文:使用
JSON.stringify()
- 设置 CSP(Content Security Policy)
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;
- 标记 Cookie 为
HttpOnly(防 JS 窃取)
分类三:跨站请求伪造(CSRF, Cross-Site Request Forgery)
🔍 原理
攻击者诱导用户访问恶意页面,利用用户已登录的身份自动发送请求(如修改密码、转账)。
💥 示例
用户登录 https://example.com 后,访问攻击者网站:
<!-- 恶意页面 -->
<img src="https://example.com/transfer?to=attacker&amount=1000" width="0" height="0">
→ 浏览器自动携带 Cookie,完成转账!
⚠️ 危害
- 非授权操作(资金、数据、权限变更)
- 用户无感知
✅ 防御
- 使用 Anti-CSRF Token
- 表单中隐藏字段:
<input type="hidden" name="csrf_token" value="RANDOM"> - 服务端校验该 token 与 Session 中一致
- SameSite Cookie 属性
Set-Cookie: sessionid=abc123; SameSite=Lax; Secure; HttpOnly
- 敏感操作要求二次验证(如短信、密码)
分类四:不安全的直接对象引用(IDOR, Insecure Direct Object Reference)
🔍 原理
应用直接使用用户可控参数作为内部对象 ID(如 /user?id=123),且未校验权限。
💥 示例
普通用户访问:
GET /api/order?id=1001 HTTP/1.1
Host: example.com
若后端未检查 id=1001 是否属于当前用户 → 可遍历查看他人订单!
⚠️ 危害
- 越权访问(水平/垂直权限绕过)
- 数据批量泄露
✅ 防御
- 基于会话的访问控制
# ✅ 检查订单是否属于当前用户
if order.user_id != current_user.id:
raise PermissionDenied()
- 使用间接引用(如 UUID 替代自增 ID)
- 默认拒绝,显式授权
分类五:安全配置错误(Security Misconfiguration)
🔍 原理
因默认配置、未打补丁、暴露调试信息等导致攻击面扩大。
💥 常见问题
- 服务器返回详细错误堆栈(暴露路径、框架版本)
- 开启目录列表(
/backup/可浏览) - 未禁用 HTTP 方法(如
TRACE,PUT) - 使用默认密码(如
admin/admin)
⚠️ 危害
- 信息泄露 → 辅助其他攻击
- 直接接管服务器
✅ 防御
- 关闭调试模式(生产环境)
- 定期更新依赖(使用
npm audit,pip-audit) - 最小化 HTTP 头信息
server_tokens off; # Nginx 隐藏版本号
- 自动化扫描(如
nmap,nikto,OWASP ZAP)
分类六:敏感数据泄露(Sensitive Data Exposure)
🔍 原理
未加密存储或传输敏感信息(密码、身份证、银行卡)。
💥 示例
- 密码明文存数据库
- HTTP 传输登录凭证
- 日志记录完整信用卡号
⚠️ 危害
- 用户身份盗用
- 法律合规风险(GDPR、CCPA)
✅ 防御
- 传输层加密:强制 HTTPS(HSTS)
- 存储加密:
- 密码:使用 bcrypt/scrypt/Argon2(非 MD5/SHA1)
- 其他数据:AES-GCM 加密
- 脱敏显示:
****1234(银行卡) - 禁止在日志/URL 中记录敏感信息
分类七:服务端请求伪造(SSRF, Server-Side Request Forgery)
🔍 原理
应用允许用户指定 URL 并由服务端发起请求(如 webhook、图片抓取),攻击者可诱使服务器访问内网资源。
💥 示例
POST /fetch-image
Host: example.com
Content-Type: application/json
{"url": "http://169.254.169.254/latest/meta-data/"} # AWS 元数据接口
→ 服务器返回云平台内部凭证!
⚠️ 危害
- 内网探测、端口扫描
- 云环境元数据泄露
- 远程代码执行(结合其他漏洞)
✅ 防御
- 禁止用户控制完整 URL
- 白名单域名/IP
if not url.startswith(("https://cdn.example.com", "https://api.trusted.com")):
raise InvalidURL()
- 禁用私有 IP 访问(10.0.0.0/8, 192.168.0.0/16 等)
- 使用专用网络代理隔离
总结:安全开发 Checklist
| 漏洞类别 | 关键防御措施 |
|---|---|
| 注入 | 参数化查询 + 输入验证 |
| XSS | 输出编码 + CSP + HttpOnly Cookie |
| CSRF | Anti-CSRF Token + SameSite Cookie |
| IDOR | 基于会话的权限校验 |
| 配置错误 | 关闭调试 + 自动化扫描 |
| 数据泄露 | HTTPS + 强哈希 + 脱敏 |
| SSRF | URL 白名单 + 禁用内网访问 |
🔐 安全不是一次性的任务,而是贯穿需求、开发、测试、部署的持续过程。
延伸建议
- 学习资源:OWASP Web Security Testing Guide
- 工具推荐:
- 开发阶段:
eslint-plugin-security(JS)、bandit(Python) - 测试阶段:Burp Suite Community, OWASP ZAP
- 监控阶段:Sentry(记录异常)、Falco(运行时防护)