我有一个服务器端渲染的React应用程序,到目前为止,Node / Express能够生成正确,稳定的ETags,从而可以利用客户端缓存。
此外,生成的HTML包含渲染阻止(非折叠)CSS和JS 内联的片段,分别为<script>
和<style>
标签,以实现更快的客户端优先渲染(由Google及其PageSpeed和Lighthouse工具所促进)。
现在,我想启用Content Security Policy (CSP),并在每个页面请求中为这些nonce
和<script>
标签提供<style>
作为属性,以避免{{1} }违规。但是,不断变化的随机数使ETag也可以根据每个请求进行更改。 HTML永远不会被缓存,每个请求都会到达我的Express服务器。
是否可以同时进行组合:
unsafe-inline
或类似功能)?
到目前为止,我发现当前性能与安全准则之间存在矛盾。
在保持HTML完整无缺的同时,是否提供CSP现时的等效项?有没有办法缓存包含CSP现时的页面?
理想情况下,我希望Express服务器中包含一个解决方案,而不必求助于我的反向代理配置,但是欢迎任何选择。
答案 0 :(得分:0)
一种解决方案是将整个内容生成和缓存留给Web应用程序(在您的情况下为Node),而将CSP nonce生成留给前端Web服务器(例如Nginx)。我已经用Django实现了它,它使用ETag进行页面缓存,执行所有Vary
头逻辑等等,并且它产生的HTML包含这样的静态CSP nonce占位符:
< script nonce="+++CSP_NONDE+++"> ... </script>
然后,Nginx使用ngx_http_subs_filter_module
填充此占位符:
sub_filter_once off;
sub_filter +++CSP_NONCE+++ $ssl_session_id;
add_header Content-Security-Policy "script-src 'nonce-$ssl_session_id'";
我看到了使用附加的Nginx模块为每个请求生成真正唯一的随机随机数的解决方案,但我认为这是一个过大的选择,我只是使用TLS会话标识符,该标识符对于每个连接的客户端都是唯一的,并且可能被缓存一段时间(例如10分钟),具体取决于您的Nginx配置。
请确保Web应用程序返回未压缩的HTML,因为Nginx将无法进行字符串替换。