What is data: & why avoid it in CSP ?

Sunday, February 1, 2026
5 min read
Theotime QuereCentralCSP Team
The data: scheme in Content Security Policy allows resources to be loaded from inline data URIs. Although convenient for small assets (e.g. tiny images or inline SVG), allowing data: in script or style directives introduces serious security risks. This article explains those risks and how to remove data: from your policy for safer coding practices.

What Is the data: Scheme?

A data URI embeds file content directly in a URL using the form data:[<media type>][;base64],<data>. Browsers resolve it like a normal URL, so CSP can treat it as a source. For example, img-src 'self' data: allows images from your origin and from inline data URIs.

Example of a data URI

Content-Security-Policy: img-src 'self' data:;

<!-- Inline image allowed by the policy -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==" alt="Pixel" />

Common Use Cases

data: is often used for:
  • Small inline images or icons (e.g. in CSS or HTML)
  • Inline SVG or other static assets
  • Legacy or third-party code that generates data URIs for scripts or styles
In img-src, font-src, or media-src, data: is sometimes used for known, non-executable content. In script-src or style-src, allowing data: is where the danger lies.

Security Vulnerabilities

When data: is allowed in script-src or style-src:
  1. XSS and code injection : Any attacker who can inject a data: URI (e.g. via a reflected parameter or stored content) can execute script or apply styles. For example, script-src 'self' data: effectively allows inline script delivered via a data URI, bypassing the protection you get from disallowing 'unsafe-inline'.

Example: data: used to inject malicious script

If script-src allows data:, an attacker can point a script's src at a data URI that contains JavaScript. The browser fetches and executes it like any other script, enabling XSS:

Malicious script injection via data: URI when script-src allows data:

Content-Security-Policy: script-src 'self' data:;

<!-- Attacker-controlled or reflected URL leads to loading this -->
<script src="data:text/javascript;base64,YWxlcnQoZG9jdW1lbnQuY29va2llKQ=="></script>
<!-- Decodes to: alert(document.cookie) - steals or exfiltrates cookies -->
  1. No origin or integrity control : Data URIs are not tied to a host. You cannot restrict them by domain or use Subresource Integrity. Any allowed data: script is a potential backdoor.
  2. Obfuscation : Attackers can encode malicious payloads in base64 data URIs, making detection and filtering harder.
For img-src, font-src, or media-src, the risk is lower (no script execution), but data: still expands the attack surface (e.g. tracking, very large payloads). Prefer hosting real assets on a controlled origin when possible.

Directives where data: should definitely not be used

Do not allow data: in any directive that controls script or style execution. Keep it out of:
  • default-src : it is the fallback directive for all the other fetching directives, so if you allow data: here, it will allow it for all other directives

  • script-src : allows execution of arbitrary JavaScript via data: URIs

  • style-src : allows injection of arbitrary CSS (e.g. exfiltration, UI abuse)

How to Remove data: and Stay Safe

  1. Move scripts and styles off data: URIs : Serve scripts and styles from your origin or a trusted CDN. Use nonces or hashes in CSP to allow only the scripts you intend.
  2. Tighten directives : Remove data: from script-src and style-src. If you must allow small images or fonts via data URIs, limit data: to img-src or font-src only and keep it out of any directive that affects script or style execution.
  3. Test with report-only : Use Content-Security-Policy-Report-Only and reporting to see what would break. Fix legitimate uses by serving resources from proper URLs, then switch to enforce mode without data:

How to safely load scripts, styles, and images without using data: URIs—host static assets on your origin or a trusted CDN.

Content-Security-Policy: script-src 'self'; style-src 'self'; img-src 'self' https://trusted-cdn.example.com;

<!-- Scripts loaded from your own origin -->
<script src="/static/js/app.js"></script>

<!-- Styles loaded from your own origin -->
<link rel="stylesheet" href="/static/css/main.css">

<!-- Images hosted on your origin or a trusted CDN -->
<img src="/static/img/logo.svg" alt="Logo" />
<img src="https://trusted-cdn.example.com/icons/arrow.png" alt="Icon" />
Using the Scanner and CSP Builder can help you see what your site currently allows and generate a policy that avoids insecure data: use.

See also

    What is data: & why avoid it in CSP ?