Scheme source
How CSP scheme sources like https, data, and blob work, and why data and blob are dangerous in script-src but safe in img-src.
Last update:
A scheme source allows every resource that uses a given URL scheme, written as
the scheme name followed by a colon, such as https:, data:, or blob:. It is
broader than a host source:
instead of naming an origin, it trusts an entire class of URLs. That breadth makes
a scheme source convenient for some resource types and dangerous for others.
A scheme source is safe for displayed content such as images and fonts, never for script:
Content-Security-Policy: img-src 'self' data:Syntax
A scheme source is a scheme name plus a colon, with no host or path. The schemes you see in a CSP are:
| Scheme | Status | Allows |
|---|---|---|
https: | ✅ Good | Any resource served over HTTPS, from any host. Very broad; prefer explicit hosts where you can. |
http: | ❌ Risky | Any resource over plain HTTP, from any host (it also matches https: URLs). |
data: | ❌ Risky | Inline data: URLs. Unsafe in script-src, style-src, and object-src; acceptable in img-src and font-src. |
blob: | ❌ Risky | blob: URLs created with URL.createObjectURL(). Unsafe in script and worker contexts. |
ws: / wss: | ✅ Good | WebSocket endpoints on connect-src (ws: also matches wss:). |
mediastream: | ✅ Good | mediastream: URLs from a capture device. Niche, media-src only. |
filesystem: | ⚠️ Deprecated | filesystem: URLs from the legacy Chromium Filesystem API, effectively obsolete. |
A bare * wildcard is not the same as a scheme source: * covers http: and
https: and any host, but deliberately excludes data:, blob:, and
filesystem:, so those must be named explicitly even alongside *.
What it matches
A scheme source matches any URL using that scheme, regardless of host, port, or
path. https: in connect-src allows a fetch() to any HTTPS endpoint
anywhere. data: in img-src allows any inline image encoded as a data: URL.
Content-Security-Policy: font-src 'self' data:That lets the page load self-hosted fonts plus any font embedded as a data:
URL, which is common when a CSS file inlines a small font.
Why data: and blob: are dangerous in script-src and style-src
A data: or blob: URL carries its own content, so allowing it in
script-src
effectively lets script run from a string the page constructs, which is the
behavior CSP exists to prevent. An attacker who can influence a data: URL, or
who injects markup that builds one, can execute arbitrary code while the policy
appears to be in force. The same applies to
style-src:
a data: stylesheet can carry injected CSS. Keep data: and blob: out of
script-src and style-src, and use a
nonce or hash
for the inline code you do trust.
Where scheme sources are safe
For non-executable resource types, a scheme source is a reasonable and common
choice. data: in
img-src
and
font-src
supports inline images and embedded fonts with little risk, because those bytes
are rendered, not executed. blob: is often needed in img-src or media-src
for object URLs the page generates. The rule of thumb: a scheme source is fine for
data you display and risky for code you run.
Insecure values to avoid
data: or blob: in script-src or style-src is the value to avoid; it opens
the inline-code path a policy is meant to close. https: in script-src is also
weak, because it trusts script from every HTTPS host on the web, which is barely
narrower than allowing any script at all. Prefer
'strict-dynamic'
with a nonce over a scheme source for script.
What it protects against
Used correctly, scheme sources let you permit a needed URL class (inline images,
generated blobs) without naming every host, while keeping executable directives
locked down. Confirm a policy has not let data: or blob: into a script
directive with the CSP evaluator.
Known bypasses and limitations
A scheme source is coarse by design: it cannot distinguish a trusted host from a
hostile one within the same scheme, so https: in connect-src allows
exfiltration to any HTTPS endpoint. When a directive needs only a few origins,
prefer host sources. The data: and blob: exclusion from * is easy to forget
and leads to broken images until the scheme is added explicitly.
Risks
The main risk is reaching for a scheme source as a quick fix when a request is
blocked, and widening a script or connection directive far more than intended.
Add the narrowest source that unblocks the resource, test it in
Report-Only mode,
and keep data:/blob: out of executable directives.
Recommendation
Use scheme sources only for displayed content, and keep script trust on a
nonce or hash
with 'strict-dynamic'.
Content-Security-Policy:
script-src 'nonce-{RANDOM}' 'strict-dynamic';
img-src 'self' data:;
font-src 'self' data:;
object-src 'none';
base-uri 'none'The OWASP CSP cheat sheet
and the web.dev strict CSP guide both warn
against data:, blob:, or a broad scheme in an executable directive; data:
in img-src and font-src is the common, acceptable exception.
Examples
Allow inline images and embedded fonts, with script locked to a nonce:
Content-Security-Policy:
default-src 'self';
img-src 'self' data:;
font-src 'self' data:;
script-src 'self' 'nonce-r4nd0m'Allow generated object URLs for media:
Content-Security-Policy: media-src 'self' blob:Browser support
Scheme sources are part of core CSP and are widely supported across current
browsers. The *-excludes-data:/blob:/filesystem: rule is consistent across
engines.