SVG上传安全漏洞 如何防范其中的XSS和XXE攻击

8次阅读

应强制白名单过滤svg:1、用xml解析器加载并禁用外部实体;2、移除script、foreignObject等高危元素;3、删除on开头事件属性及危险href值。

SVG上传安全漏洞 如何防范其中的XSS和XXE攻击

如果您允许用户上传SVG文件,攻击者可能通过嵌入恶意脚本或外部实体触发xss或XXE攻击。以下是防范此类风险的具体措施:

一、服务端强制SVG内容白名单过滤

仅允许SVG规范中明确安全的元素、属性和事件处理函数,剥离所有潜在执行能力的标签与属性,从根本上阻断脚本注入路径。

1、解析上传的SVG文件为dom树,使用xml解析器(如python的xml.etree.ElementTree或java的DocumentBuilder)加载并禁用外部实体解析。

2、遍历所有节点,移除包含scriptforeignObjectanimatesethandler等高危元素的节点。

3、检查每个属性,删除以on开头的事件属性(如onclickonload)、xlink:hrefhref(当值以javascript:开头时)以及style中含expression(url(引用外部资源的片段。

4、对保留的viewBoxfillstroke等展示类属性进行正则校验,仅接受预设格式的值。

二、禁用XML外部实体并关闭DTD解析

XXE攻击依赖XML解析器加载外部DTD或实体定义,通过配置解析器拒绝所有外部声明,可彻底消除该攻击面。

1、在Java中使用DocumentBuilderFactory时,调用setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)并设置setFeature("http://xml.org/sax/features/external-general-entities", false)

2、在PHP中使用libxml时,在解析前执行libxml_disable_entity_loader(true),并在simplexml_load_string()DOMDocument::loadXML()前确保该设置生效。

3、在Node.js中使用svgsonfast-xml-parser时,显式将ignoreAttributes设为false并禁用allowDoctypeignoreDeclaration选项,同时不启用parseNode回调中的任意代码执行逻辑。

三、转换为静态图像并剥离XML结构

将SVG彻底转化为无交互能力的栅格图像(如PNG),消除所有XML语义与可执行上下文,适用于仅需展示用途的场景。

1、使用服务端渲染工具(如Puppeteer、Resvg或Inkscape CLI)加载原始SVG,设置超时与沙箱限制,避免无限循环或内存耗尽。

2、指定输出分辨率为固定DPI(如96),裁剪至合理画布尺寸(如最大2000×2000像素),防止过大资源消耗。

3、生成PNG后,验证其二进制头为x89PNGrnx1an,且文件大小处于预期区间(如5KB–5MB),拒绝异常文件。

4、将生成的PNG作为最终存储文件,原SVG文件立即删除,数据库中仅保存PNG路径与元信息。

四、响应头与CSP策略协同防御

即使SVG内容被误放行,通过HTTP响应头与内容安全策略可限制其执行环境,降低XSS实际危害。

1、对所有SVG响应设置Content-Type: image/svg+xml,并附加X-Content-Type-Options: nosniff,防止浏览器MIME嗅探误判为HTML。

2、在返回SVG的HTTP头中加入X-Frame-Options: DENYReferrer-Policy: no-referrer,切断iframe嵌套利用与Referer泄露路径。

3、若SVG需在网页中内联渲染,主页面CSP策略必须显式禁止script-src 'none',且不允许'unsafe-inline''unsafe-eval',同时限制img-src仅指向可信CDN域名。

五、上传前客户端轻量校验与服务端二次验证

客户端校验可快速拦截明显恶意文件,但不可替代服务端验证;两者结合形成纵深校验链。

1、前端JavaScript读取文件二进制内容,使用new Blob([file]).text()获取字符串,用正则检测是否存在DOCTYPEENTITY等关键词,匹配即阻止提交。

2、提取SVG根节点后的xmlns属性值,仅允许http://www.w3.org/2000/svg,拒绝http://www.w3.org/1999/xhtml等混杂命名空间。

3、服务端接收后,再次解析字节流,比对SHA-256哈希值是否与前端传递的校验值一致,防止绕过前端校验的篡改请求。

4、对同一用户连续上传行为做频率限制(如5分钟内最多3次SVG上传),并记录原始文件SHA-256与解析日志,供审计追溯。

text=ZqhQzanResources