我很难找到问题的答案,这无疑是因为我不知道要搜索什么,但我希望这里有人可以提供帮助:)
我已经在托管 React 应用程序的节点应用程序中使用随机数实现了头盔。
节点应用程序中的头盔实现:
app.use((req, res, next) => {
res.locals.cspNonce = crypto.randomBytes(16).toString("hex");
next();
});
app.use(
helmet.contentSecurityPolicy({
useDefaults: true,
directives: {
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`],
styleSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`],
},
})
);
我的整个 React 应用程序中唯一导入脚本和样式表的地方是我的 index.html 页面的头部。所以我的问题是,我需要在下面的脚本和链接标签中添加什么才能正确使用带有随机数的 CSP?
反应应用程序index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
nonce="What to put here, if it even goes here?"
/>
<script
type="text/javascript"
src="https://code.jquery.com/jquery.min.js"
nonce="How do I implement the res.locals.cspNonce here?"
>
</script>
<title>Some title</title>
React 应用程序大多是 SPA,其中页面内容不会完全从服务器重新加载,而是通过 XMLHttpRequest() 部分刷新。
因此,当页面的各个部分“重新加载”时,刷新“nonce”的值是不存在技术可能性的,因为当页面以这种方式“刷新”时,
<meta http-equiv='Content-Security-Pilicy'...>
部分中的<head>
无法更改。'hash-values'
而不是随机数。
React应用中的
'nonce-value'
只有在整个页面使用服务器端渲染时才能使用,这有很多陷阱并且很少使用。而在这种情况下,应用程序将失去 React 的所有好处。
随机数应通过模板注入,以便在访问路由时始终生成的随机数始终是最新的。
这里是头盔维护员。
您应该设置
nonce
和 <link>
标签的 <script>
属性。例如,如果生成的 nonce
是 abc123def456
,您将执行以下操作:
<script nonce="abc123def456" src="https://example.com/script.js"></script>
因为随机数只能一次性使用,所以不能将随机数与静态 HTML 一起使用。换句话说,您需要服务器端 HTML 渲染才能使用 CSP 随机数。
如果这对您来说是个问题,则不必使用随机数。可能还有其他方法可以解决该问题,例如使用 CSP 哈希脚本。
这是一个创建 React + Webpack 应用程序以使用 Node 和 Nginx 服务器在每次页面刷新时生成 CSP 随机数的示例。