29

I'm getting the error below in the console of my browser:

Content Security Policy: The page’s settings blocked the loading of a resource at http://localhost:3000/favicon.ico (“default-src”).

I searched online and saw that this should be fixed with the snippet of code below:

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

I added this to my front-end app.component.html file (the parent template for all my front-end views), but this didn't work as expected.

I've also tried multiple permutations thereupon to no avail.

My front-end is at localhost:4200 and back-end at localhost:3000.

Below is the snippet of code from my back-end server (middleware):

app.use(cors());
app.options('*',cors());
var allowCrossDomain = function(req,res,next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}
app.use(allowCrossDomain);

I also have now added the following middleware to my backend (Express) server:

const csp = require('express-csp-header');

app.use(csp({
  policies: {
      'default-src': [csp.SELF, 'http://localhost:3000/', 'http://localhost:4200/' ],
      'script-src': [csp.SELF, csp.INLINE],
      'style-src': [csp.SELF],
      'img-src': ['data:', 'favico.ico'],
      'worker-src': [csp.NONE],
      'block-all-mixed-content': true
  }
}));

. . . but still hasn't fixed the problem.

Here is a screenshot:

enter image description here

What am I doing wrong and how can I fix it?

nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
Crowdpleasr
  • 3,574
  • 4
  • 21
  • 37
  • You have the serve your resources also over https. One file can break the whole chain. – Honsa Stunna May 30 '19 at 22:19
  • 3
    Where is the original CSP being set (presumably the server, in a header)? If you're simply trying to debug your policy and added all those extra allow lines, that's ok, but if that's what you plan to put in production, you might as well just remove the CSP altogether. You should understand what the CSP's purpose is in order to configure it properly. https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP – msanford May 30 '19 at 22:39

4 Answers4

21

Content Security Policy (CSP) is a mechanism to help prevent Cross-Site Scripting (XSS) and is best handled at server side; please note it can be handled at client side as well, making use of the <meta> tag element of your HTML.

When configured and enabled, a web server will return the appropriate Content-Security-Policy in the HTTP response header.

You may want to read more about CSP on the on the HTML5Rocks website and Mozilla developer page here and here.

Google CSP Evaluator is a handy and free online tool to help test CSP for your website or web application.

In your instance, you may need to add the line below without enforcing HTTPS as protocol using the https: directive;
Because your website or application (as shared) is not available over HTTPS.

res.header('Content-Security-Policy', "img-src 'self'");

Starting with default-src directive set to none is a great way to start deploying your CSP settings.

In case you opt to use the Content-Security-Policy middleware for Express , you may get started as illustrated in the snippet below;

const csp = require('express-csp-header');
app.use(csp({
    policies: {
        'default-src': [csp.NONE],
        'img-src': [csp.SELF],
    }
}));

// HTTP response header will be defined as:
// "Content-Security-Policy: default-src 'none'; img-src 'self';"

Remember CSP are case or application specific and based on your project requirements.

As such, you need to fine tune in order to meet your need.

AvahW
  • 2,083
  • 3
  • 24
  • 30
nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
  • Many thanks. I set `default-src` to `none` on both front- and back- end, but that still didn't fix the problem. Any other ideas? Tks! – Crowdpleasr May 30 '19 at 23:24
  • @Crowdpleasr: Did you set `img-src` to `self`? Please do and share a screenshot of your console browser should you still have a challenge. – nyedidikeke May 30 '19 at 23:27
  • Thank you. I set `img-src` to `self` on both front and back end, and also added a screenshot of console browser. Many thanks again for all your help! – Crowdpleasr May 30 '19 at 23:44
  • 1
    The crazy thing is that the app was working fine for several days. Then I added a `POST` route to back-end today, and now I suddenly have this CSP problem which I can't get rid of. – Crowdpleasr May 30 '19 at 23:55
  • Do remember to keep your code clean and free of bloat; there's no need implementing CSP everywhere. Server-side, in your HTTP response header is the most effective option. – nyedidikeke May 30 '19 at 23:56
  • OK, got it. Please note I never added any CSP anywhere. I only started toying with CSP after I started getting those "errors". – Crowdpleasr May 30 '19 at 23:57
  • You should check your code for the culprit script, or possibly a browser extension. – nyedidikeke May 31 '19 at 00:02
  • Very strange! The "challenge" is over `favicon.ico`, and I searched my entire codebase, and the only instance of `favicon.ico` is in the `index.html` file (front-end, which is at `localhost:4200`). So I eliminated the favicon.ico html `href` so no favicon.ico left in the codebase, but two strange things: FIRSTLY, I'm still getting the "challenge" even with `favicon.ico` gone, and SECONDLY the challenge references `*localhost:3000*/favicon.ico`, but `favicon.ico` was on the `*localhost:4200*` client side. – Crowdpleasr May 31 '19 at 00:16
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194205/discussion-between-nyedidikeke-and-crowdpleasr). – nyedidikeke May 31 '19 at 00:22
  • As @nyedidikeke suggested, getting rid of CSP on client-side solved the issue! – Crowdpleasr May 31 '19 at 00:47
  • @Crowdpleasr. I'm facing the same issues. But none of the above answers helped. I even removed `` from my `index.html` but still same error. Please help me. – Tanzeel Oct 06 '19 at 06:29
  • @Tanzeel [Let's continue this discussion in chat](https://chat.stackoverflow.com/rooms/200465/tanzeel). – nyedidikeke Oct 06 '19 at 12:32
  • 9
    Continuing the discussion in chat does not help the rest of us who are trying to solve this issue. – E.Bradford Oct 12 '19 at 01:01
  • Newer is directives instead of policies. – alekshandru Jun 05 '23 at 11:12
3
  • /favicon.ico is automatically loaded by the web browser in the absence of other URLs for the favicon. This is specified by: https://html.spec.whatwg.org/multipage/links.html#rel-icon
  • You current Content-Security-Policy was blocking it. You need to use something like: Content-Security-Policy: img-src 'self'

Ideally web browser shouldn't even try /favicon.ico when it would be blocked. After all, loading /favicon.ico is triggered by the web browser, not the developer. I patched chrome (version >= 88) to remove the error:

https://chromium-review.googlesource.com/c/chromium/src/+/2438388


user3840170
  • 26,597
  • 4
  • 30
  • 62
ArthurS
  • 350
  • 3
  • 5
1

If you have a strict CSP header for e.g. images and other static files like

Content-Security-Policy: default-src 'none';

then Firefox will assume that it also means that the implicit reference to /favicon.ico used for tab icon is also banned. Chrome has internal special case where the implicit /favicon.ico is always allowed no matter the CSP header. To grant Firefox access to implicit /favicon.ico you have to add img-src 'self' at minimum.

Content-Security-Policy: default-src 'none'; img-src 'self';

Also note that the syntax of Content-Security-Policy policy only supports allowing specific origins and not URLs. The original question had img-src ... favicon.ico where it should have just said img-src ... 'self'. (CSP version 2 has limited support for prefix path within an origin but it has pretty complex edge cases with redirects so you should avoid using that feature if possible at all.)

Mikko Rantalainen
  • 14,132
  • 10
  • 74
  • 112
0

nyedidikeke's answer is awesome !

With express-csp-header middleware, set the policies to pass CSP.
https://www.npmjs.com/package/express-csp-header

Here is my ndoejs code :

const { expressCspHeader, INLINE, NONE, SELF } = require('express-csp-header');
const app = express();
// other app.use() options ...
app.use(expressCspHeader({ 
    policies: { 
        'default-src': [expressCspHeader.NONE], 
        'img-src': [expressCspHeader.SELF], 
    } 
}));  

enjoy !!

Jason Hsu
  • 41
  • 4