1

I'm want to create a link in my website who download a PDF file but I get a white window with:

Cannot GET /file

and a Content Security Policy (CSP) error:

Content Security Policy: The page settings prevented a resource from loading at inline ("default-src").

I use ExpressJs and Nginx for the back-end.

I've tried to set CSP default-src header like this in my app.js file:

//Headers setup
app.use((req, res, next) => {
    res.setHeader('Content-Security-Policy',"default-src 'self' https://www.mydomain.fr");
    next();
});

i've also tried to add this in my .conf file in Nginx:

add_header Content-Security-Policy "default-src 'self';" always;

It is still not working. Do you have any idea what is wrong?

My router:

const express = require('express');
const router = express.Router();

const fileController = require('../controllers/file');

router.get('/', fileController.getFile);

module.exports = router;

My controller:

const path = require('path');

exports.getFile = (req, res, next) => {
    res.set({'Content-Type':'application/pdf'});
    res.set({'Content-Disposition':'attachment, filename=file.pdf'});
    const filePath = path.join(__dirname, '/public/documents/file.pdf');
    res.download(filePath, 'file.pdf', (e) => {res.status(404).json({e: e})});
}
SabSab43
  • 11
  • 3
  • 1
    Are you using [Helmet](https://www.npmjs.com/package/helmet) or similar? Or any Nginx config relating to it? I don't think Express/Nginx has any CSP rules by default. – jonrsharpe Jan 05 '21 at 15:05
  • no I just set this header on my app. My nginx conf file don't have any header inside – SabSab43 Jan 05 '21 at 15:33
  • `res.setHeader()` is a native NodeJS method, I do not know is it avaliable here. Use `res.set({ "Content-Security-Policy": "default-src 'self';" })` or the alias `res.header({ "Content-Security-Policy": "default-src 'self';" })`. Or use [packages](https://csplite.com/csp211/#CSP_ExpressJS) – granty Jan 06 '21 at 08:23
  • hello, i've tried your code and the code example in csplite.com. None of this works... – SabSab43 Jan 06 '21 at 11:39

3 Answers3

0

I guess your resource is embedded inline (see the csp error).

To allow that use unsafe-inline:

app.use((req, res, next) => {
    res.setHeader('Content-Security-Policy',"default-src 'self' 'unsafe-inline'");
    next();
});
tom
  • 9,550
  • 6
  • 30
  • 49
0

SabSab43, you have been given the correct leads in the comments and answers, but you shouldn't recklessly publish the CSP. You can publish CSP in several ways:

  • add_header in Nginx
  • HTTP header via res.setHeader()
  • specialized Helmet package
  • using <meta http-equiv='Content-Security-Policy' content="...CSP rules here..."> in the HTML code.

But if you do use all of above at the same time, you'll publish a several different CSPs and as result more restrictive one will acts.

Therefore remove all CSP you added and lets go step by step:

  1. Do check the jonrsharpe's remark abt Helmet. The fact is that if you have Helmet 4 connected to Express, it issues the restrictive default-src 'self' policy by default.

Therefore after removing all your CSPs, check do you have CSP header in browser, tutorial is here. If CSP header is presents - some middleware (like Helmet) does publish it. You need to find it and modify the policy in it, or switch it off and use your res.setHeader(...)

  1. If there is no header (and there is no meta tag either), publish the CSP with any of the methods, and add 'unsafe-inline' to it, as kmgt said. You need to have policy:
    "default-src 'self' 'unsafe-inline' https://www.mydomain.fr"
    to get rid of "The page settings prevented a resource from loading at inline ("default-src")"

Note that 'prevented a resource from loading at inline' can be about not only inline <script>, but about inline <style> too. But since you use `default-src', it covers both.

PS: Chrome's console more verbose than Firefox's one. If you fail to fix this issue, pls show the message about the blocking from the Сhrome's console - it will show the rules that block.

granty
  • 7,234
  • 1
  • 14
  • 21
0

I've deleted all my CSP Rules (I don't use Helmet or any CSP dependencies) in my app and Nginx .conf file and when I look in browsers developers tools I see again the CSP Rule.

In chrome: capture

In Firefox: capture

therefore, I've tried to put this code:

app.use((req, res, next) => {
    res.set({"Content-Security-Policy":"default-src 'self' 'unsafe-inline' https://www.myDomain.fr"});
    next();
});

I've the same result than without the CSP Rules...

In Chrome I juste have a 404 error:

GET https://www.myDomain.fr/file 404 (Not found)

In Firefox

GET https://www.myDomain.fr/file [HTTP/1.1 404 Not found 96ms]

Content Security Policy: The page settings prevented a resource from loading at inline ("default-src").

The 404 is probably caused by the CSP Error...

SabSab43
  • 11
  • 3