2025-11-27-前端安全-关于XSS与CRSF及其相关对策
最后更新时间:
页面浏览: 加载中...
跨站脚本攻击(XSS)和跨站请求伪造(CSRF)
跨站脚本攻击(Cross-Site Scripting,简称 XSS)和跨站请求伪造(Cross-Site Request Forgery,简称 CSRF 或 XSRF)是 Web 应用中最常见的两种安全漏洞。尽管名称相似,但攻击原理、影响和防御方式完全不同。
1. 跨站脚本攻击(XSS)
定义:XSS 是一种代码注入攻击,攻击者将恶意客户端脚本(通常为 JavaScript)注入到网页中,当受害者访问该页面时,恶意脚本在受害者的浏览器中执行,从而窃取信息或执行恶意操作。
分类:XSS 攻击主要分为三种类型。首先是反射型 XSS(Reflected XSS),恶意脚本通过 URL 参数、表单提交等反射回响应页面,常用于钓鱼攻击,例如用户点击含有<script>alert(document.cookie)</script>的链接。其次是存储型 XSS(Stored/Persistent XSS),恶意脚本被永久存储在服务器(如数据库中的评论、帖子),所有访问该内容的用户均受影响,危害最大。最后是基于 DOM 的 XSS(DOM-based XSS),恶意脚本通过客户端 JavaScript 操作 DOM 注入,通常不涉及服务器反射。
攻击后果:XSS 攻击可能导致多种严重后果。攻击者可以窃取 Cookie、Session Token,导致会话劫持;伪造请求、钓鱼、键盘记录;还可以对页面进行篡改(Defacement)。
防御措施:针对 XSS 攻击有多种防御措施。输出编码(Output Encoding)是在 HTML、JavaScript、CSS、URL 等上下文中对用户输入进行适当转义(如使用 DOMPurify 净化 HTML);内容安全策略(Content Security Policy, CSP)通过 HTTP 头限制脚本来源;输入验证则是严格验证和过滤用户输入;HttpOnly Cookie 可以防止 JavaScript 访问 Cookie;使用安全库如 DOMPurify、OWASP Java Encoder 等也是有效手段。
详细防御策略:在具体实施中,HTML 编码将特殊字符(<、>、&、”、’)转换为 HTML 实体,防止浏览器将其解释为标签。JavaScript 编码在 JavaScript 上下文中使用用户输入前,将特殊字符转义为 JavaScript 字符串或正则表达式格式。CSS 编码在 CSS 上下文中使用用户输入时,需要转义特殊字符。URL 编码则对 URL 参数进行编码,确保 URL 安全。
CSP 实施示例可以通过 HTTP 头设置:
1 | |
也可以在 HTML 中设置
1 | |
使用模板引擎的安全特性也很重要,如 Jinja2、Handlebars 等模板引擎通常内置 XSS 防护,使用时避免使用”raw”或”unsafe”过滤器。同时需要进行严格的输入验证,不仅在服务端验证输入,也要在客户端进行验证(虽然客户端验证可被绕过,但可以改善用户体验)。
2. 跨站请求伪造(CSRF)
定义:CSRF 是一种利用用户已认证身份的攻击。攻击者诱导已登录的用户在不知情情况下向目标网站发送恶意请求,利用浏览器自动携带 Cookie 的特性执行敏感操作。
攻击原理:首先,用户已登录目标网站(如银行网站),浏览器保存了认证 Cookie。然后,攻击者通过钓鱼邮件、恶意网站诱导用户访问含有恶意表单或图像的页面,例如 HTML 中的<img src="https://bank.com/transfer?amount=1000&to=attacker">
最后,浏览器自动携带 Cookie 发送请求,完成转账等操作
攻击后果:CSRF 攻击可能导致未经授权执行敏感操作(如转账、修改密码、删除账户)。虽然它不直接窃取数据,但可利用用户权限造成破坏。
防御措施:针对 CSRF 有多种防御措施。CSRF Token(同步器令牌)是在表单或请求中加入服务器生成的随机 Token,服务器验证 Token 是否匹配且有效,主流框架(如 Django、Spring、Rails)内置支持。SameSite Cookie 是设置 Cookie 的 SameSite 属性(Lax 或 Strict),限制跨站请求携带 Cookie,其中 SameSite=Lax 允许顶级导航(如 GET 链接),阻止大多数 CSRF;SameSite=Strict 完全阻止跨站请求携带 Cookie。双重提交 Cookie(Double Submit Cookie)是将 Token 同时存入 Cookie 和表单,服务器比对两者(适用于无状态应用)。验证 Referer/Origin 头是检查请求来源是否合法(可被伪造或禁用,不推荐单独使用)。使用安全的 HTTP 方法是敏感操作仅允许 POST、PUT、DELETE 等非幂等方法。
详细防御策略:CSRF Token 的实现包括几个步骤:服务器生成随机的 CSRF Token(如使用加密安全的随机数生成器);将 Token 放入表单隐藏字段或 HTTP 头中;用户提交请求时,服务器验证 Token 是否匹配且未过期;Token 应在每次会话或关键操作后更新。
SameSite Cookie 设置示例包括设置 SameSite 属性:
1 | |
自定义请求头验证要求所有 API 请求包含自定义头部(如 X-Requested-With 或 X-CSRF-Token),因为浏览器在跨站请求中不会自动添加这些头部。验证码机制对高风险操作(如修改密码、转账)要求用户输入验证码或进行二次确认。登出确认在登出页面添加确认步骤,防止攻击者诱导用户登出。
XSS 与 CSRF 的对比总结
| 项目 | XSS | CSRF |
|---|---|---|
| 攻击目标 | 浏览器中的信任(执行恶意脚本) | 网站对用户的信任(利用已认证会话) |
| 是否需要注入代码 | 是(注入 JavaScript) | 否(仅诱导发送请求) |
| 主要危害 | 窃取数据、会话劫持、页面篡改 | 伪造用户操作(如转账、改密) |
| 典型场景 | 用户输入未过滤的评论、搜索框 | 登录后访问恶意网站 |
| 核心防御 | 输出编码、CSP、输入验证 | CSRF Token、SameSite Cookie |
| 是否可相互利用 | XSS 可绕过 CSRF 防御(直接读 Token) | CSRF 无法直接引发 XSS |
综合防御策略:在实际安全防护中,需要采用多种策略。分层防御是结合多种防御措施,而不是依赖单一方法。安全默认值是在系统设计时就考虑安全因素,而不是事后补救。定期安全审计使用自动化工具和手动测试来识别潜在的安全漏洞。开发者培训提高团队对安全问题的认识和防范能力。监控和日志记录可疑活动,及时发现攻击尝试。
实际应用示例:在实际开发中,我们通常会组合使用多种防御策略。例如 JavaScript 代码示例中,createSecureForm 函数首先验证输入数据,然后对输出进行编码,最后添加 CSRF Token,这样就结合了多种安全措施。
1 | |
攻击者若成功执行 XSS,可轻松绕过 CSRF Token(通过脚本读取并发送 Token),因此,在 Web 安全开发中,必须同时防御这两种漏洞。