Jordan
Jordan

Reputation: 117

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“default-src”)

I understand there are many similar questions. However, I'm still new to MERN and I am looking for a simplified answer to this problem.

I'm following a tutorial on the MERN stack, the application is a simple expense calculator and all the functionality worked great until we moved on to adding Express and Mongoose. Here's the server.js file so you can see my mess:

const path = require('path');
const express = require('express');
const dotenv = require('dotenv');
const colors = require('colors');
const morgan = require('morgan');
const transactions = require('./routes/transactions');
const connectDB = require('./config/db');

dotenv.config({ path: './config/config.env' });

connectDB();

const app = express();

app.use(express.json());


if(process.env.NODE_ENV === 'development') {
    app.use(morgan('dev'));
}

app.use('api/v1/transactions', transactions);

if(process.env.NODE_ENV === 'production') {
    app.use(express.static('client/build'));

    app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html')));
}

const PORT = process.env.PORT || 5000;

app.listen(PORT, console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`));

I'm importing everything correctly in package.json so there's probably no need to spam the chat with that. I'm connected to Mongodb, though I'm sure that doesn't make a difference. Anyways, when I use the command to start it, (npm run start), the server goes up on localhost:5000 and I immediately see Cannot GET / on the html page. In the console on Firefox I get the error:

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“default-src”). injectGlobalHook.js:513:49

On Chrome it says:

... it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

Also in my terminal it shows GET / 404 2.201 ms - 139, but only when I refresh the page. So I know that the error has to do with CSP, and it's in a file I shouldn't touch and haven't touched, but I don't know how to fix it. I've had the error before, but I think I just gave up on that project. An answer would be nice, but an explanation as to why I'm getting this error would be better. Thanks!

Upvotes: 7

Views: 25122

Answers (2)

Dan
Dan

Reputation: 595

I highly suggest to secure your headers with helmet library (https://helmetjs.github.io/), but you need to be careful because by default helmet will block your page scripts e.g. AJAX requests, so when using defaults you will get error such as: Content Security Policy: The page's settings blocked the loading of a resource at inline ("default/src") or similar, to fix this I needed to write helmet options manually.

In my project I was using the following configuration:

app.use(
    helmet.contentSecurityPolicy({
      useDefaults: false,
      "block-all-mixed-content": true,
      "upgrade-insecure-requests": true,
      directives: {
        "default-src": [
            "'self'"
        ],
        "base-uri": "'self'",
        "font-src": [
            "'self'",
            "https:",
            "data:"
        ],
        "frame-ancestors": [
            "'self'"
        ],
        "img-src": [
            "'self'",
            "data:"
        ],
        "object-src": [
            "'none'"
        ],
        "script-src": [
            "'self'",
            "https://cdnjs.cloudflare.com"
        ],
        "script-src-attr": "'none'",
        "style-src": [
            "'self'",
            "https://cdnjs.cloudflare.com"
        ],
      },
    }),
    helmet.dnsPrefetchControl({
        allow: true
    }),
    helmet.frameguard({
        action: "deny"
    }),
    helmet.hidePoweredBy(),
    helmet.hsts({
        maxAge: 123456,
        includeSubDomains: false
    }),
    helmet.ieNoOpen(),
    helmet.noSniff(),
    helmet.referrerPolicy({
        policy: [ "origin", "unsafe-url" ]
    }),
    helmet.xssFilter()

I disabled default to write everything manually, since I might have external scripts, requests etc. so I needed to define them additionally.

This configuration will solve blocked resource errors like:

  • Content Security Policy: The page's settings blocked the loading of a resource at inline ("default/src")
  • Content Security Policy: The page's settings blocked the loading of a resource at inline ("img/src")
  • Content Security Policy: The page's settings blocked the loading of a resource at inline ("script/src")

Upvotes: 4

Sergi Juanati
Sergi Juanati

Reputation: 1416

The CSP can be defined either in your index.html (front-end) or in the web server (back-end).

In case of front end, you should find something like:

<html>
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=11"/>
        <meta http-equiv="Cache-Control" content="no-cache"/>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self';"/>
        <title>
        </title>
    </head> 

According to your error message, you need to replace

default-src 'none'

by

default-src 'self'

As for the back-end, apparently there is no CSP reference in your NodeJS code.

Upvotes: 5

Related Questions