1

我正在将我的 NodeJS(http+websocket)/vanillaJS 移动到 express+websocket/(希望是 React)。我想用 ExpressJS 为 script-src 实现 CSP-nonce,用于静态文件。我已经设法使用加密和头盔 csp 动态设置标题。

但是,我坚持在每个脚本标签上设置 nonce 值并仍在使用 express.static 函数(在 docs/web/stacko 上也找不到任何东西......)我只是替换了原始 http 模块'<script type="text/javascript"' 部分与 nonce 生成的值。

有没有办法做到这一点并且仍然使用 express-static?(我知道它说的是静态的,但这似乎是一个有用的功能,即使对于静态文件)。如果没有(因为我是新来表达的)是否有标准/最佳实践方式来做到这一点?还是一个众所周知的使用模块?谢谢!

4

2 回答 2

1

好吧,似乎有两种方法可以做到这一点:

  1. 一种是不使用 express-static,而是专门提供文件(请参阅 soothsayer 答案)或使用带有 Express 的模板引擎

  2. 另一个仍然使用 express-static 的解决方案是使用另一个动态替换的中间件。我找到了两个例子:一个更轻一个更高级 (regex & etc)。它们似乎都以相同的方式工作:它们临时修改 express-static() 中使用的 res.write() 和 res.end() 函数以进行字符串替换,然后恢复为原始形式并调用它们。

从现在开始我正在研究 SPA,我使用了简单的解决方案 (1)。如果需要更多页面,我可能会切换到模板引擎或解决方案 (2)。如果解决方案(2)有任何缺点,我很想知道它们。

于 2021-10-14T18:14:06.133 回答
0

你必须在你的脚本中设置一个特殊的字符串,你将用你将要生成的随机随机数替换它。就我而言,我将其设置为“random-csp-nonce”。因此,我将阅读我的文件并用随机生成的 nonce 替换“random-csp-nonce”。不幸的是,我猜你必须为每个文件编写这样的路由。

app.get('/', function(req, res, next) {
  // path to file
  const filePath = path.resolve(__dirname, '../frontend/dist', 'index.html');

  // read the file
  fs.readFile(filePath, 'utf8', function (err,data) {
    if (err) {
        return console.log(err);
    }

    // generate nonce and set it on header
    res.locals.nonce = uuidv4().replace(/\-/g, '');
    res.header('Content-Security-Policy', "default-src 'self';style-src 'self' `'nonce-${res.locals.nonce}'`;"
  
    // replace the special string with nonce
    result = data.replace('random-csp-nonce', res.locals.nonce);
    res.send(result);
  });
});

参考 - https://codereview.stackexchange.com/questions/180251/send-html-with-nonce-for-each-script-and-style-tag-on-each-request

于 2021-06-21T10:23:32.197 回答