跳转至

Web应用安全

Web应用安全

OWASP Top 10/XSS/SQL注入——保护Web应用免受攻击

📋 本章目标

完成本章学习后,你将能够:

  1. 理解OWASP Top 10安全风险
  2. 掌握XSS攻击原理与防护
  3. 理解SQL注入及防护措施
  4. 掌握CSRF防护方法
  5. 学会安全编码实践

1. OWASP Top 10

1.1 OWASP Top 10 (2021)

Text Only
OWASP Top 10 - 2021
═══════════════════

┌──────┬────────────────────────────────────────┬───────────┐
│ 排名 │ 漏洞类型                              │ 风险等级  │
├──────┼────────────────────────────────────────┼───────────┤
│ A01  │ 访问控制失效 (Broken Access Control)   │ 高        │
│ A02  │ 加密失败 (Cryptographic Failures)      │ 高        │
│ A03  │ 注入 (Injection)                      │ 高        │
│ A04  │ 不安全设计 (Insecure Design)           │ 中高      │
│ A05  │ 安全配置错误 (Security Misconfiguration)│ 中高     │
│ A06  │ 易受攻击的组件 (Vulnerable Components) │ 中高      │
│ A07  │ 认证失败 (Authentication Failures)     │ 高        │
│ A08  │ 软件和数据完整性失败                   │ 高        │
│ A09  │ 日志监控失败 (Logging Failures)        │ 中        │
│ A10  │ 服务器端请求伪造 (SSRF)               │ 中高      │
└──────┴────────────────────────────────────────┴───────────┘

2. XSS攻击

2.1 什么是XSS

跨站脚本攻击 (XSS) 是攻击者向Web页面注入恶意脚本的攻击方式。

Text Only
XSS攻击流程
════════════

1. 攻击者注入恶意脚本
   ┌─────────────────────────────────────────────┐
   │ 评论内容: <script>steal(cookie)</script>   │
   └─────────────────────────────────────────────┘
2. 服务器存储(未过滤)
   ┌─────────────────────────────────────────────┐
   │ 数据库: 存储了包含恶意脚本的评论            │
   └─────────────────────────────────────────────┘
3. 其他用户浏览页面
   ┌─────────────────────────────────────────────┐
   │ 页面渲染: 恶意脚本在用户浏览器执行          │
   │ Cookie被盗 → 攻击者获取用户会话            │
   └─────────────────────────────────────────────┘

2.2 XSS类型

类型 说明 示例场景
反射型 脚本从URL参数反射 搜索结果页
存储型 脚本存储在服务器 评论、帖子
DOM型 脚本在客户端执行 JavaScript动态渲染

2.3 XSS防护

Python
# ❌ 不安全代码
def unsafe_display(user_input):
    return f"<div>{user_input}</div>"

# ✅ 安全代码 - 输出编码
import html
def safe_display(user_input):
    return f"<div>{html.escape(user_input)}</div>"

# ✅ 安全代码 - Content Security Policy
# HTTP响应头设置:
# Content-Security-Policy: default-src 'self'; script-src 'self'

# ✅ 安全代码 - HttpOnly Cookie
# Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict

3. SQL注入

3.1 什么是SQL注入

SQL注入是攻击者通过构造恶意输入来操纵数据库查询的攻击。

Text Only
SQL注入示例
════════════

正常查询:
─────────────────────────
SELECT * FROM users
WHERE username = 'admin' AND password = 'password123'

攻击者输入:
─────────────────────────
username: admin' --
password: anything

注入后查询:
─────────────────────────
SELECT * FROM users
WHERE username = 'admin' --' AND password = 'anything'

效果: 注释掉密码验证,直接登录admin账户

3.2 SQL注入防护

Python
import sqlite3

# ❌ 不安全: 字符串拼接
def unsafe_login(username, password):
    query = f"SELECT * FROM users WHERE username='{username}'"
    cursor.execute(query)

# ✅ 安全: 参数化查询
def safe_login(username, password):
    query = "SELECT * FROM users WHERE username=? AND password=?"
    cursor.execute(query, (username, hashed_password))

# ✅ 安全: ORM框架
from sqlalchemy.orm import Session
from models import User

def orm_login(db: Session, username: str):
    return db.query(User).filter(User.username == username).first()

# ✅ 其他防护措施
"""
• 使用最小权限原则配置数据库账户
• 输入验证和白名单
• 使用存储过程
• WAF防护
"""

4. CSRF攻击

4.1 什么是CSRF

跨站请求伪造 (CSRF) 是攻击者诱导用户在已登录状态下执行非预期操作。

Text Only
CSRF攻击流程
════════════

1. 用户登录银行网站 bank.com
   ┌─────────────────┐
   │ 用户已认证      │
   │ Cookie: session │
   └─────────────────┘

2. 用户访问攻击者网站 evil.com
   ┌─────────────────────────────────────────────┐
   │ <img src="bank.com/transfer?to=attacker&amount=10000"> │
   └─────────────────────────────────────────────┘

3. 浏览器自动携带Cookie发送请求
   ┌─────────────────────────────────────────────┐
   │ 银行服务器收到转账请求                      │
   │ Cookie有效 → 转账成功                       │
   └─────────────────────────────────────────────┘

4.2 CSRF防护

Python
from flask_wtf.csrf import CSRFProtect

# ✅ 方法1: CSRF Token
csrf = CSRFProtect(app)

# 前端表单
# <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">

# ✅ 方法2: SameSite Cookie
# Set-Cookie: session=abc; SameSite=Strict

# ✅ 方法3: 验证Referer头
def verify_referer(request):
    referer = request.headers.get('Referer', '')
    if not referer.startswith('https://mysite.com'):
        raise ValueError("Invalid referer")

# ✅ 方法4: 双重Cookie验证
def double_submit_cookie(request):
    cookie_token = request.cookies.get('csrf_token')
    header_token = request.headers.get('X-CSRF-Token')
    return cookie_token == header_token

5. 安全编码实践

5.1 输入验证

Python
import re
from pydantic import BaseModel, EmailStr, constr  # Pydantic数据验证模型

# ✅ 使用数据验证框架
class UserInput(BaseModel):
    username: constr(min_length=3, max_length=20, pattern=r'^[a-zA-Z0-9_]+$')
    email: EmailStr
    age: int = None

    class Config:
        # 拒绝额外字段
        extra = 'forbid'

# ✅ 白名单验证
ALLOWED_FILE_TYPES = {'jpg', 'png', 'gif'}

def validate_file_type(filename):
    ext = filename.rsplit('.', 1)[-1].lower()  # 负索引:从末尾倒数访问元素
    if ext not in ALLOWED_FILE_TYPES:
        raise ValueError(f"Invalid file type: {ext}")
    return ext

5.2 安全配置清单

Text Only
# 安全配置清单

## HTTPS
- [ ] 强制HTTPS重定向
- [ ] HSTS头启用
- [ ] 证书有效性检查

## Cookie
- [ ] HttpOnly标志
- [ ] Secure标志
- [ ] SameSite=Strict/Lax

## 安全头
- [ ] X-Content-Type-Options: nosniff
- [ ] X-Frame-Options: DENY
- [ ] Content-Security-Policy
- [ ] X-XSS-Protection

## 认证
- [ ] 密码强度要求
- [ ] 登录失败限制
- [ ] 多因素认证
- [ ] 会话超时

6. 面试题精选

Q1: 如何防止XSS攻击?

参考答案: 1. 输出编码:对用户输入进行HTML编码 2. CSP策略:限制脚本来源 3. HttpOnly Cookie:防止Cookie被JS读取 4. 输入验证:过滤特殊字符

Q2: 什么是参数化查询?为什么重要?

参考答案: 参数化查询使用占位符代替直接拼接用户输入,数据库引擎会将参数视为数据而非SQL代码,从而防止SQL注入。

Q3: 如何防护CSRF攻击?

参考答案: 1. CSRF Token验证 2. SameSite Cookie属性 3. 验证Referer头 4. 关键操作要求二次确认


7. 学习检查清单

完成本章学习后,请确认你能够:

  • 列出OWASP Top 10主要漏洞
  • 解释XSS攻击原理和防护方法
  • 实现参数化查询防止SQL注入
  • 配置CSRF Token防护
  • 应用安全编码最佳实践

参考资料


最后更新日期:2026-02-17 适用版本:网络安全教程 v2026