22

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.

13

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.

  • Thank you. I'm not sure I can do anything about using base64 images. Thank you for the recommendation. – Martin Verner Jul 27 '15 at 4:29
  • 11
    data:image/svg+xml is invalid. You can't add anything behind the protocol. – Dag Høidahl Apr 25 '17 at 8:47
  • 1
    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
  • 1
    @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 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
  • 1
    @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
20
  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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.