Is including the data scheme in your Content Security Policy safe?

  1. The note on whitelisting the data protocol which is referenced says

    data: Allows data: URIs to be used as a content source. This is insecure; an attacker can also inject arbitrary data: URIs. Use this sparingly and definitely not for scripts.

    This is not in a part specific to the risks of data uris in images, and I have not seen any substantiative evidence that data uris in images can execute code in a modern browser any respect, nevermind XSS a page.

    In certain contexts, an SVG image can execute Javascript code, but these are either child contexts such as <iframe>, <object> or <embed> elements, or a direct part of the host DOM i.e. <svg> elements.

    MDN calls out explicitly that <img> embedded SVGs cannot execute Javascript, along with some other security restrictions, saying

    • JavaScript is disabled.
    • External resources (e.g. images, stylesheets) cannot be loaded, though they can be used if inlined through data: URIs.
    • :visited-link styles aren't rendered.
    • Platform-native widget styling (based on OS theme) is disabled.
  2. It doesn't appear to be possible to specify a MIME as part of the data: protocol whitelisting statement as suggested as a possible mitigation. The only content security policy directive I've seen able to restrict MIME type is plugin-types, which restricts only for <object> and <embed> (see general CSP docs).

I will agree with the accepted answer in the respect that if you don't have to use data-uris, and can do so with little pain, it's easier to just keep your CSP and not use them. However, if you're working with images at all, that is usually a huge pain.


This is a great question, and I commend you taking the time to think about this from a security perspective rather than knee-jerk implement the solution from the link you sent.

Yes, as you have feared, use of data: in a CSP directive is unsafe, since this allows for XSS vulnerabilities to be opened up as data: can handle any URI. This is spelled out in Mozilla's CSP Documentation.

You can decrease the surface area of a potential XSS attack by changing the data: directive to:

img-src 'self' data:image/svg+xml

However, as a best practice I would endeavor to address the root issue about the images being provided as base64 and see if that can be done another way so as not to require modification of the CSP directive.