48

I have a Cordova app that transforms some images to base64. This violates CSP with this message:

Refused to load the image 'data:image/svg+xml;charset=US-ASCII,%3C%3Fxml%20version%3D%221.0%22%20encod…E%3C%2Fg%...%3C%2Fsvg%3E' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

According to this answer, I can simply add data: to my Content-Security-Policy meta, but I would very much like to know, if this is safe? data: does not specify origin and therefore I fear it's unsafe.

isherwood
  • 105
  • 4
Martin Verner
  • 585
  • 1
  • 4
  • 8

2 Answers2

44
  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 substantive evidence that data URIs in images can execute code in a modern browser any respect, never mind 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.
  1. 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.

isherwood
  • 105
  • 4
zemnmez
  • 561
  • 4
  • 2
27

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. and in this W3C Working Draft

There is no way in CSP to specify "allow only SVG images to be embedded via data URIs, but no any other type of URIs". CSP just lets you specify data:.

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.

Herringbone Cat
  • 4,242
  • 15
  • 19
  • 23
    `data:image/svg+xml` is invalid. You can't add anything behind the protocol. – Dag Høidahl Apr 25 '17 at 08:47
  • 4
    As @DagHøidahl mentioned, `data:image/svg+xml` does not work. Does anyone know the proper directive to specify to allow _only_ SVG images to be embedded via `data` URIs, but no any other type of URIs? – Yevgeniy Brikman Jul 21 '18 at 21:34
  • 8
    @YevgeniyBrikman There is no way in CSP to specify *“allow only SVG images to be embedded via data URIs, but no any other type of URIs”*. CSP just lets you specify `data:`, and when you specify that, you’re allowing any resources to be embedded using `data:` — including scripts. That’s why specifying `data:` isn’t safe and should be avoided. See https://www.w3.org/TR/CSP3/#csp-directives — *“developers SHOULD NOT include either 'unsafe-inline', or data: as valid sources in their policies. Both enable XSS attacks by allowing code to be included directly in the document itself.”* – sideshowbarker Aug 10 '18 at 21:56
  • 10
    @sideshowbarker Thanks, I suspected that was the case. It's a bit of a problem, as _many_ libraries (esp. CSS/font libraries) rely on loading images via data URIs. So now I have to choose between an ugly and secure website or a beautiful and insecure website. – Yevgeniy Brikman Aug 11 '18 at 22:05
  • 2
    Does allowing arbitrary data URIs make an application vulnerable to XSS with a CSP like `default-src 'self' data`? Even if a resource, say a script, is loaded through use of a `data:` URI, it can't talk cross-site because of `'self'` in the CSP header. So there is no XSS vulnerability, is it? – amn Aug 09 '21 at 11:38