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:

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:

  1. 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.
  2. Enforce Correct Content-Type: Always serve SVGs with Content-Type: image/svg+xml.
  3. Use Content-Disposition: When user uploads are involved, serving the file with Content-Disposition: attachment forces a download instead of rendering the file in the browser, bypassing the browser’s execution engine entirely.