如何在 ExpressJs 应用程序上配置 Content-Policy-Security 标头?

时间:2021-01-05 15:02:02

标签: node.js express header content-security-policy

我想在我的网站上创建一个下载 PDF 文件的链接,但出现一个白色窗口:

Cannot GET /file

和内容安全策略 (CSP) 错误:

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

我使用 ExpressJs 和 Nginx 作为后端。

我尝试在我的 app.js 文件中像这样设置 CSP default-src 标头:

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

我也尝试将其添加到 Nginx 的 .conf 文件中:

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

它仍然无法正常工作。你知道出了什么问题吗?

我的路由器:

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

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

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

module.exports = router;

我的控制器:

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})});
}

3 个答案:

答案 0 :(得分:0)

我猜你的资源是内嵌的(参见 csp 错误)。

要允许使用 unsafe-inline

app.use((req, res, next) => {
    res.setHeader('Content-Security-Policy',"default-src 'self' 'unsafe-inline'");
    next();
});

答案 1 :(得分:0)

SabSab43,您已经在评论和答案中获得了正确的线索,但您不应该鲁莽地发布 CSP。您可以通过多种方式发布 CSP:

  • Nginx 中的 add_header
  • 通过 res.setHeader() 的 HTTP 头
  • 专业头盔包
  • 在 HTML 代码中使用 <meta http-equiv='Content-Security-Policy' content="...CSP rules here...">

但如果您同时使用上述所有内容,您将发布多个不同的 CSP,因此会采取更严格的行为。

因此删除您添加的所有 CSP 并让我们一步一步来:

  1. 请务必检查 jonrsharpe 的评论 abt Helmet。事实上,如果您将 Helmet 4 连接到 Express,它会默认发布限制性 default-src 'self' 策略。

因此,在删除所有 CSP 后,请检查浏览器中是否有 CSP 标头,教程为 here。如果存在 CSP 标头 - 某些中间件(如 Helmet)会发布它。您需要找到它并修改其中的政策,或者将其关闭并使用您的 res.setHeader(...)

  1. 如果没有标头(并且也没有元标记),请使用任何方法发布 CSP,并添加 'unsafe-inline',如 kmgt 所说。你需要有政策:
    "default-src 'self' 'unsafe-inline' https://www.mydomain.fr"
    摆脱“页面设置阻止资源在内联加载(“default-src”)”

请注意,“阻止资源在内联加载”不仅可以与内联 <script> 相关,还可以与内联 <style> 相关。但是由于您使用了 `default-src',它涵盖了两者。

PS:Chrome 的控制台比 Firefox 的控制台更冗长。如果您未能解决此问题,请从 Сhrome 的控制台显示有关阻止的消息 - 它会显示阻止的规则。

答案 2 :(得分:0)

我已经删除了我的应用程序和 Nginx .conf 文件中的所有 CSP 规则(我不使用 Helmet 或任何 CSP 依赖项),当我查看浏览器开发人员工具时,我再次看到了 CSP 规则。

在铬: capture

在 Firefox 中: capture

因此,我试着把这段代码:

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

我的结果与没有 CSP 规则的结果相同...

在 Chrome 中,我有一个 404 错误:

<块引用>

GET https://www.myDomain.fr/file 404(未找到)

在火狐中

<块引用>

GET https://www.myDomain.fr/file [HTTP/1.1 404 未找到 96 毫秒]

<块引用>

内容安全策略:页面设置阻止资源在内联加载(“default-src”)。

404 可能是由 CSP 错误引起的...

相关问题