User-uploaded SVG files may embed malicious code or include it via an external reference. When a malicious SVG file is published on your website, it can be used to exploit multiple attack vectors, including:
<image>
, <script>
, or <use>
tags to send sensitive information to attacker-controlled servers.<image xlink:href="file:///...">
or <use>
references to attempt to read local or server-side files.Indeed, wrapping the image in an <img>
tag is 1 of the 3 measures you can take.
Other measures are
More detailed guidance on each measure:
<img>
TagInstead of directly embedding an SVG using <svg>
or <object>
, use the <img>
tag to render it:
<img src="safe-image.svg" alt="Safe SVG">
The <img>
tag ensures that the SVG is treated as an image and prevents JavaScript execution inside it, but it doesn’t remove malicious code from the SVG file.
Enabling the Content Security Policy (CSP) HTTP response header also prevents JavaScript execution inside the SVG.
For example:
Content-Security-Policy: default-src 'none'; img-src 'self'; style-src 'none'; script-src 'none'; sandbox
Which applies the following policy:
Directive | Purpose |
---|---|
default-src 'none' |
Blocks all content by default. |
img-src 'self' |
Allows images only from the same origin. |
style-src 'none' |
Prevents inline and external CSS styles. |
script-src 'none' |
Blocks inline and external JavaScript to prevent XSS. |
sandbox |
Disables scripts, forms, and top-level navigation for the SVG. |
Strip potentially harmful elements like <script>
, <iframe>
, <foreignObject>
, inline event handlers (e.g. onclick
) or inclusion of other (potentially malicious) files.
Examples of libraries for SVG sanitization:
1 I started the mentioned Java sanitizer project, as I could not find any solution for Java.
Render the SVG server side to a raster based format, like PNG. This may protect visiting users, but could introduce vulnerabilities at the rendering side at the server, especially using server side JavaScript (like Node.js).