是否有可能使用 Next.js + Styled-Components 和静态主机(例如 S3)制定有意义/安全的内容安全策略

Posted

技术标签:

【中文标题】是否有可能使用 Next.js + Styled-Components 和静态主机(例如 S3)制定有意义/安全的内容安全策略【英文标题】:Is It Possible to Have a Meaningful/Secure Content Security Policy With Next.js + Styled-Components and a Static Host (eg. S3) 【发布时间】:2021-12-01 12:36:57 【问题描述】:

最近,Google 的 Lighthouse 工具提醒我,我没有提供内容安全政策。但是,当我尝试添加一个(或至少一个没有“不安全”一词的)时,我最终会遇到一堆违规行为,似乎来自 Next.js 和 Styled-Components。

这两个库似乎都使用了违反任何理智 CSP 的动态脚本/样式标签。但是the only way I've found 解决它们是使用“nonce”。但是,这似乎需要运行实际的服务器:如果您使用 Next 生成静态文件(托管在 AWS S3 等静态主机上),则不能提供 nonces。

我的问题很简单:我错过了什么吗?是否有一些非基于 nonce 的方式或基于静态主机 nonce 的方式来使用 Next.js 和 Styled Components 在 S3 上托管网站?

或者是否不可能将这些库与严格的 CSP 一起使用(没有服务器生成的随机数)?

【问题讨论】:

【参考方案1】:

希望你:

不要使用像<tag style='display:none;'>这样的内联样式或element.setAttribute('style', ...)的JS调用。

不要使用像<tag onclick='...'>这样的内置内联事件处理程序和像<a href='javascript:void(0)'>这样的JS-navigation

因为上述所有都需要 'unsafe-inline' 在样式/脚本中,因为 'unsafe-hashes' 令牌不受 Safary 支持,而 Firefox 则严重支持。

对于单页应用程序 (SPA)(没有服务器端渲染),使用 'nonce-value' 没有用,因为 SPA 不会重新加载页面,而只是部分更新其内容,但您必须为每个页面生成新的随机数页面加载。

对于无服务器应用(如静态文件托管)和 SPA 应用,您可以使用 'hash-value' 而不是 'nonce-value' 来允许内联脚本和样式。 如果您使用 Webpack,它有一些插件,例如,csp-html-webpack-plugin 插件将为您的 Content Security Policy 元标记生成内容,并将正确的数据输入到您的 HTML 模板中,由html-webpack-plugin 生成。所有内联的 JS 和 CSS 都将被散列,并插入到策略中。

【讨论】:

以上是关于是否有可能使用 Next.js + Styled-Components 和静态主机(例如 S3)制定有意义/安全的内容安全策略的主要内容,如果未能解决你的问题,请参考以下文章

在 Next.js 中为 styled-jsx 动态添加样式

在next.js中使用styled-component以及全局主题切换

Next.js 和 Styled Components 在刷新时服务器和客户端之间不同步

如何在 Next.js 的活动页面上设置链接组件的样式

如何将 Nextjs + styled-components 与 material-ui 集成

带有 Next.js 和样式化组件的本地字体