How CSP Blocks Script Execution in SVG Files
Scalable Vector Graphics (SVG) are XML-based documents capable of containing interactive scripts, making them a potential vector for Cross-Site Scripting (XSS) attacks. Content Security Policy (CSP) mitigates this risk by enforcing strict boundaries on where and how scripts execute inside SVG files, dictating script evaluation rules based on how the graphic is embedded, served, and parsed by the browser.
The Role of Embedding Context
The mechanism by which CSP restricts scripts in an SVG depends on how the SVG is loaded into a web document:
- Image Context (
<img>tags, CSSbackground-image): Browsers automatically block all script execution inside SVGs loaded as standard images for security reasons, operating in an isolated security context regardless of the parent page’s CSP. - Inline SVGs (
<svg>directly in HTML): The SVG elements become part of the parent Document Object Model (DOM). In this context, the parent document’s CSP directly governs all embedded<script>tags and inline event handlers (such asonloadoronclick). - Frame Contexts (
<object>,<iframe>,<embed>, or Direct Navigation): The SVG is treated as an independent document. It creates its own browsing context and does not inherit the parent document’s script restrictions unless governed by framing directives or served with its own dedicated CSP headers.
Key CSP Directives Governing SVG Scripts
1. script-src and
default-src
When an SVG is embedded inline or loaded directly as an XML document,
the script-src directive controls script evaluation: *
Disallowing Inline Scripts: By omitting
'unsafe-inline' from script-src, browsers
block inline <script> tags and event handlers (e.g.,
<circle onload="alert(1)"/>) inside the SVG. *
Complete Script Disallowance: Setting
script-src 'none' or default-src 'none'
completely disables any JavaScript execution within the SVG
document.
2. object-src
SVGs loaded through <object> or
<embed> tags run in their own document context. The
parent page can restrict or completely disable the ability to load
external SVGs via these tags: * object-src 'none' blocks
all plugins and media objects, preventing SVGs from being rendered via
<object> or <embed>. * Specifying
trusted domains (e.g.,
object-src 'self' https://trusted.cdn.com) ensures only
verified SVGs can be loaded as embedded documents.
3. sandbox
The sandbox directive can be returned by the server
hosting the SVG file or applied via an <iframe>.
Applying sandbox without the allow-scripts
token strips all script execution capabilities, forcing the SVG to be
rendered as an untrusted, script-less document.
Applying CSP to Standalone SVG Files
When users or applications access an SVG file directly via a URL, the SVG relies entirely on the HTTP response headers sent with it. To neutralize script execution for standalone SVGs:
- Serve a Dedicated CSP Header: Include
Content-Security-Policy: default-src 'none'; script-src 'none'; style-src 'self' 'unsafe-inline';in the HTTP response headers for the SVG file. - Enforce Correct Content-Type: Always serve SVGs
with
Content-Type: image/svg+xml. - Use Content-Disposition: When user uploads are
involved, serving the file with
Content-Disposition: attachmentforces a download instead of rendering the file in the browser, bypassing the browser’s execution engine entirely.