聚焦三大高危漏洞:SQL 注入、CSRF、XSS
1. SQL 注入(SQL Injection)
攻击原理
攻击者通过在用户输入中嵌入恶意 SQL 片段,绕过应用逻辑,直接操作数据库。
示例(危险代码):
# 危险!字符串拼接user_id=request.GET['id']query=f"SELECT * FROM users WHERE id ={user_id}"# 输入: 1 OR 1=1 --cursor.execute(query)→ 可导致:数据泄露、删除表、提权、远程命令执行(如 PostgreSQL 的 COPY TO)
防御手段
| 方法 | 说明 | Python 实践 |
|---|---|---|
| 参数化查询(Prepared Statements) | 最有效!SQL 结构与数据分离 | SQLAlchemy / Django ORM 默认安全;原生 SQL 使用cursor.execute("SELECT * FROM t WHERE id = %s", (user_id,)) |
| 禁用动态 SQL 拼接 | 绝不拼接用户输入到 SQL 字符串 | 避免f"..."、str.format()构造 SQL |
| 最小权限原则 | DB 用户仅授予必要权限 | 不使用 root 连接数据库 |
| 输入校验 + 白名单 | 对 ID、枚举值等做类型/范围检查 | int(user_id)、正则校验 |
| ORM 安全使用 | 避免raw()、extra()拼接 | Django 中慎用User.objects.extra(where=[f"name = '{name}'"]) |
关键点:只要使用参数化查询,99% 的 SQL 注入可被杜绝。
2. 跨站请求伪造(CSRF, Cross-Site Request Forgery)
攻击原理
攻击者诱导已登录用户访问恶意网站,该网站自动向目标站点(如银行)发起带 Cookie 的请求(如转账),利用用户身份执行非意愿操作。
前提:用户已登录目标站 + 请求无二次验证。
防御手段
| 方法 | 说明 | Python 框架支持 |
|---|---|---|
| CSRF Token | 每个表单/请求携带一次性 token,服务端校验 | Django 内置({% csrf_token %}+CsrfViewMiddleware)Flask-WTF 提供 csrf_token()⚠️ FastAPI 需手动实现或用 fastapi_csrf_protect |
| SameSite Cookie | 设置Cookie: SameSite=Lax/Strict | 所有框架均可配置(Django 默认Lax) |
| 双重提交 Cookie | Token 同时放在 Cookie 和 Header,比对一致 | 适用于无状态 API(但不如 Token 安全) |
| 敏感操作二次验证 | 如支付需短信/密码确认 | 业务层防御 |
注意:
- 纯 API 服务(如移动端后端)通常不需要 CSRF 防护(因不依赖 Cookie 认证,改用 Token);
- 若 Web 前后端同域且用 Cookie 登录,则必须启用 CSRF。
3. 跨站脚本攻击(XSS, Cross-Site Scripting)
攻击原理
攻击者将恶意脚本(JavaScript)注入网页,当其他用户浏览时执行,窃取 Cookie、会话、钓鱼等。
分类:
- 存储型 XSS:恶意脚本存入 DB(如评论区)
- 反射型 XSS:脚本通过 URL 参数反射(如搜索框)
- DOM 型 XSS:前端 JS 动态写入未转义内容
示例:
<!-- 用户输入: <script>alert(document.cookie)</script> --><p>{{ user_comment }}</p><!-- 直接渲染 → 脚本执行! -->防御手段
| 层级 | 措施 | Python 实践 |
|---|---|---|
| 输出编码(Output Encoding) | 在渲染到 HTML 时转义特殊字符 | Jinja2(Flask/Django)默认自动转义 FastAPI + Jinja2 同样安全 ⚠️ 若用 ` |
| 内容安全策略(CSP) | 限制脚本来源,禁止内联脚本 | 添加响应头:Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com→ Django 用 django-csp,Flask 用flask-talisman |
| 输入过滤(辅助) | 对富文本使用白名单过滤 | 用bleach库清理 HTML:bleach.clean(html, tags=['p', 'strong'], attributes={}) |
| HttpOnly Cookie | 阻止 JS 读取 Cookie | Django/Flask/FastAPI 均支持设置session_cookie_httponly = True |
关键原则:
- 永远不要信任用户输入;
- 转义发生在输出时,而非输入时(避免双重转义);
- 富文本场景必须用
bleach等库做语义清洗。
通用安全加固建议(Python 项目)
| 类别 | 措施 |
|---|---|
| 依赖安全 | 定期扫描:pip-audit、safety;锁定版本(requirements.txt+pip-tools) |
| 错误信息 | 生产环境关闭详细错误(DjangoDEBUG=False,FastAPI 关闭debug) |
| 安全头 | 启用:X-Content-Type-Options: nosniff、X-Frame-Options: DENY(防点击劫持) |
| 认证安全 | 密码哈希用bcrypt/argon2(Django 默认);会话超时;多因素认证(MFA) |
| 日志审计 | 记录关键操作(登录、支付),但不记录密码/Token |
推荐工具 & 库(Python)
| 漏洞 | 工具/库 |
|---|---|
| SQL 注入 | SQLAlchemy, Django ORM(天然防护) |
| CSRF | Django 内置, Flask-WTF, fastapi_csrf_protect |
| XSS | bleach(HTML 清洗),jinja2(自动转义) |
| CSP | django-csp,flask-talisman |
| 依赖扫描 | pip-audit,safety,trivy(容器扫描) |
| 安全头 | secure(WSGI 中间件),fastapi.middleware.trustedhost |
安全 Checklist(上线前必查)
- 所有数据库查询使用参数化(无字符串拼接)
- Web 表单启用了 CSRF Token(若使用 Cookie 认证)
- 用户生成内容在 HTML 输出时自动转义
- 富文本字段经
bleach清洗 - 生产环境
DEBUG = False - Session Cookie 设置
HttpOnly+Secure(HTTPS) - 启用 CSP(至少
default-src 'self') - 依赖无已知 CVE(
pip-audit扫描通过)
总结:
SQL 注入 → 用参数化查询
CSRF → 用 Token(Web 场景)
XSS → 输出转义 + CSP
安全是“纵深防御”,单点防护不足,需多层叠加!