25

I don't know where to apply the Content Security Policy (CSP) snippet below in my code;

Content-Security-Policy: script-src 'self' https://apis.google.com

Should it be in the HTML?

Will it be best implemented in JavaScript as in the code snippet below?

var policy = "default-src 'self'";
http.createServer(function (req, res) {
    res.writeHead(200, {
        'Content-Security-Policy': policy
    });
});
nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
user2520410
  • 459
  • 1
  • 5
  • 12

3 Answers3

30

You just need to set it in the HTTP Header, not the HTML. This is a working example with express 4 with a static server:

var express = require('express');
var app = express();


app.use(function(req, res, next) {
    res.setHeader("Content-Security-Policy", "script-src 'self' https://apis.google.com");
    return next();
});

app.use(express.static(__dirname + '/'));

app.listen(process.env.PORT || 3000);

If you want more information about CSP, this is an excelent article: http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Hope that helps!

colecmc
  • 3,133
  • 2
  • 20
  • 33
  • 3
    In case this help, here's my Express middleware layer I'm using to set the CSP headers in a way thats easy to update - https://medium.com/@mdp/csp-in-express-js-node-157d040f2f00 – mdp Oct 13 '15 at 17:38
  • When you set the header in node as shown in this answer, does that effect *client side* js requests to third parties, ie can it block and allow get requests made from the browser to a third party site? or is it only applied to *server side* js? (also, it seems you *can* set CSP in the `` of an html document - https://content-security-policy.com/examples/meta - but i'm not sure if that is the best approach, in [my case](https://stackoverflow.com/q/63649311), the directives in the `` section are simply not being applied) – user1063287 Aug 30 '20 at 13:40
  • Update to answer the question in my comment above - yes, setting CSP headers in the node app effects client side js behaviour as well, as demonstrated in [my answer here](https://stackoverflow.com/a/63658248). – user1063287 Aug 30 '20 at 14:09
2

For a node.js application without using any external framework e.g. express:

const http = require('http');

http.createServer((request, response) => {

    request.on('error', (err) => {
        console.error(err);

    // for this simple example I am not including the data event
    // e.g. if the request contains data in the body

    }).on('end', () => {

       response.on('error', (err) => {
           console.error(err);
       });

      // you can set your headers with setHeader or 
      // use writeHead as a "shortcut" to include the statusCode. 
      // Note writeHead won't cache results internally
      // and if used in conjuction with setHeader will take some sort of "precedence"

      response.writeHead(200, {
          "Content-Security-Policy": "default-src 'self'"

           // other security headers here...
      });

      response.end("<html><body><h1>Hello, Security Headers!</h1></body></html>");

  });
}).listen(8080);

See the node.js documentation for more details on setting headers on the response object

rags2riches-prog
  • 1,663
  • 1
  • 10
  • 22
2

If you are using Express, I suggest taking a look at helmet. In addition to increased options & flexibility (handling CSP violations, nonces...etc), there are a lot of inconsistencies in how browsers implement CSP. Helmet looks at the user-agent of the browser and sets the appropriate header and value for that browser. If no user-agent is matched, it will set all the headers with the 2.0 spec.

// Make sure you run "npm install helmet-csp" to get the csp package.
const csp = require('helmet-csp')

app.use(csp({
  directives: {
    defaultSrc: ["'self'"],
    styleSrc: ["'self'", 'maxcdn.bootstrapcdn.com']
  }
}))
Kevin Farrugia
  • 6,431
  • 4
  • 38
  • 61