51

I have an app, in which the user would be able to copy an image URL, paste it unto an input and the image will be loaded on a box.

But my app, keeps triggering this message:

Refused to load the image 'LOREM_IPSUM_URL' because it violates the following Content Security Policy directive: "img-src 'self' data:".

That's my meta tag:

<meta http-equiv="Content-Security-Policy" content="default-src *; 
img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; 
style-src  'self' 'unsafe-inline' *">

I'm using html2Canvas within the app, and when I remove this: "img-src 'self' data:"

It fires this error:

html2canvas.js:3025 Refused to load the image 'data:image/svg+xml,
<svg xmlns='http://www.w3.org/2000/svg'></svg>' because it violates
the following Content Security Policy directive: "default-src *". 
Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

Along with a bunch of other errors.

Jason Aller
  • 3,475
  • 28
  • 40
  • 37
Rafael de Castro
  • 825
  • 3
  • 16
  • 34

5 Answers5

69

Try replacing this part:

img-src * 'self' data: https:;

So the complete tag:

<meta http-equiv="Content-Security-Policy" content="default-src *;
   img-src * 'self' data: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *;
   style-src  'self' 'unsafe-inline' *">

Content Security Policy Reference

manzapanza
  • 5,774
  • 4
  • 37
  • 47
  • 35
    but isn't this defeating its purpose img-src * 'self' data: https: that is security? – setzamora Dec 07 '17 at 01:49
  • 3
    you are invalidating the security allowing all, with * – francogp Oct 03 '19 at 13:05
  • 9
    "I'm having a guest over while I'm at work and I'd like to let them into my house, how can I do this?" This answer is the "just rip the door off the hinges and let anyone in" equivalent. *Don't do this.* There is a reason those keys are called `unsafe-`. – msanford Jun 11 '20 at 19:00
30

img-src * 'self' data: https:; is not a good solution as it can make your app vulnerable against XSS attacks. The best solution here should be: img-src 'self' data:image/svg+xml. If it doesn't work try: img-src 'self' data:Consider changing it if you still have your directive as img-src * 'self' data: https:;

Donald Shahini
  • 727
  • 8
  • 19
  • 18
    I would just like to add, to anyone reading this going forward, that adding anything after the port in `data:` does'nt work. I.e. you can't set `data:image/svg+xml`. It only allows to set `data:`. – confuse Mar 03 '21 at 17:16
  • I am using [helmet](https://www.npmjs.com/package/helmet). Disabling the `contentSecurityPolicy` solved the issue for me. – A. Berta Nov 24 '21 at 12:05
  • 3
    @A. Berta - Disabling the CSP does not solve the issue as it disables CSP. The question is not how to make the error go away. It is how to get the img to work with CSP enabled. Cheers! – Scott Skiles Jan 20 '22 at 22:19
  • Are there any realistic scenarios where allowing `data:` in your `img-src` would open you up to a security issue? – Ryan McGrath Feb 20 '22 at 17:59
2

In addition to what has been contributed above by @manzapanza, you need to make sure if the CSP hasn't been configured in your application's web config file because if the setting exists it will override your meta tag setting in your index file like in the example below:

Index meta tag:

<meta http-equiv="Content-Security-Policy" content="default-src *;img-src * 'self' data: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; style-src  'self' 'unsafe-inline' *">

Being overridden by a CSP setting in your web config file.

Web config setting:

<add name="Content-Security-Policy" value="default-src https: http: 'unsafe-inline'; img-src * 'self' data: https:;" />

In a case like this, consider having one set mostly in the system's web config file.

Haz23
  • 21
  • 1
2

For helmet users. Better practice instead of setting contentSecurityPolicy to false which should be the most last option. I used this in my app and it solves the issue very well. My app is hosted here. Checkout my source code here.

app.use(
  helmet.contentSecurityPolicy({
    useDefaults: true,
    directives: {
      "img-src": ["'self'", "https: data:"]
    }
  })
)
Charleskimani
  • 398
  • 4
  • 19
-2

This simply solves the problem:

img-src 'self' data:

But ensure multiple directives are separated using a semicolon (;)