【问题标题】:Helmet Content Security Policy Global Path not working头盔内容安全策略全局路径不起作用
【发布时间】:2021-01-12 03:31:00
【问题描述】:

我正在使用 Helmet 在后端使用 Express 设置我的 Web 应用程序的内容安全策略。政策如下所示:

const express = require("express");
const app = express();
const helmet = require('helmet');

app.use(helmet());
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "https://ajax.googleapis.com"],
      imgSrc: ["https://firebasestorage.googleapis.com"],
      objectSrc: ["'none'"],
      styleSrc: ["'self'", "https://maxcdn.bootstrapcdn.com/bootstrap", "https://www.w3schools.com"],
      upgradeInsecureRequests: [],
    },
  })
);

当我的应用尝试访问诸如https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css 之类的链接时。它说它违反了 styleSrc 政策。但是我已经指定了允许https://maxcdn.bootstrapcdn.com/bootstrap 的策略之一,我认为https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css 也会被接受,因为它是一个子src。但显然它被阻止了。那我该如何让孩子 src 通过呢?我试过https://maxcdn.bootstrapcdn.com/bootstrap*但是无效。

【问题讨论】:

    标签: javascript express content-security-policy websecurity helmet.js


    【解决方案1】:

    这里是 Helmet 的作者。

    尝试添加尾部斜杠,如下所示:

    https://maxcdn.bootstrapcdn.com/bootstrap/
    

    这是因为/bootstrap 不允许您执行/bootstrap/3.4.0/css/bootstrap.min.css 之类的操作,但/bootstrap/ 可以。这是内容安全策略的事情,而不是头盔的事情。

    有关详细信息,请参阅the "Matching Source Expressions" section in the CSP spec 的第 11 步:

    如果源表达式包含一个非空的path-part,并且该URL 不是重定向的结果,那么:

    1. 如果path-part 的最后一个字符不是U+002F SOLIDUS 字符(/),则精确匹配true,否则为false
    2. source-expression-path-list 是在 U+002F SOLIDUS 字符 (/) 上拆分 path-part 的结果。
    3. 如果 source-expression-path-list 的长度大于 url-path-list 的长度,则返回不匹配。
    4. 对于 source-expression-path-list 中的每个 entry
      1. 百分比解码条目
      2. url-path-list中第一项的解码百分​​比。
      3. 如果 entry 不是 url-path-list 中第一项的不区分大小写的 ASCII 匹配,则返回 不匹配
      4. 从列表中弹出 url-path-list 中的第一项。
    5. 如果精确匹配true,且url-path-list不为空,则返回不匹配。李>

    顺便说一句,您可能希望将您的 Helmet 代码清理为如下所示:

    app.use(helmet({
      contentSecurityPolicy: {
        directives: {
          // ...
        },
      },
    }));
    

    您的代码使用helmet(),其中包括一些默认的CSP 中间件,然后用helmet.contentSecurityPolicy() 覆盖它。没什么大不了的,但只使用一次更正确。

    【讨论】:

    • 谢谢埃文,我会试试的。我只想指出我读过你的书Express in Action,并且喜欢它。读起来很有趣,我学到了很多东西。
    • 效果很好。谢谢你。顺便说一句,我还有一个小问题。每次更新头盔的contentSecurityPolicy 时,我都需要在相应的 HTML 文件中进行更改以应用最新的策略。每次保存更改时,我都使用nodemon 重新启动我的服务器。但似乎最新的政策无法通过 HTML 文件的更改来应用。你知道是什么导致了这个问题吗?
    • 我的猜测:当您更改 HTML 时,Nodemon 不会重新启动。不过,不确定您的应用的复杂性。
    猜你喜欢
    • 2023-02-23
    • 2021-12-25
    • 1970-01-01
    • 2021-06-11
    • 2023-04-03
    • 2015-01-24
    • 2016-09-10
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多