【问题标题】:Nuxt + Vuetify using Content Security Policy (CSP) header inline stylingNuxt + Vuetify 使用内容安全策略 (CSP) 标头内联样式
【发布时间】:2021-07-29 18:39:49
【问题描述】:

对于我的公司,我需要更新我们的 Nuxt + Vuetify 应用程序以使用内容安全策略 (CSP) 标头。 'unsafe-inline' 不允许用于 'default-src'。我们目前面临的问题是 Vuetify 在运行时给 DOM 元素添加样式属性。

例如:

<div id="app">
  <v-system-bar app>
    <v-container>Content</v-container>
  </v-system-bar>
</div>

结果:

<div class="v-system-bar v-system-bar--fixed theme--light" style="height: 24px;">
    <div class="container">Content</div>
</div>

CSP 标头不允许style="height: 24px"。这给了我以下错误:

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src https://unpkg.com/ 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-gGKtWVlwtb9dj1Sa7K4ybKpqUOE61nkachaCJ1LfmFY='), or a nonce ('nonce-...') is required to enable inline execution.

其他 vuetify 组件也会出现此问题,v-system-bar 只是一个示例。我知道可以为&lt;style&gt; 元素添加随机数,但不能为style 属性添加随机数。除了将标头设置为unsafe-inline之外,有没有办法解决这个问题?我想继续使用 Vuetify 和 CSP 标头。

这是一个 codepen 链接:https://codepen.io/erikeuserr/pen/WNpbOwx

提前致谢!

【问题讨论】:

    标签: vue.js nuxt.js vuetify.js content-security-policy


    【解决方案1】:

    style="height: 24px" 这样的结构出现在代码中是vue.js(不是vuetify.js)脚本工作的结果。 vue.js 使用 el.setAttribute() 函数来设置 style= 属性。 el.setAttribute('style', ...) 被 CSP 视为不安全,因此 vue.js 与 CSP 不兼容。

    但是el.style.property = '...' 是安全的,所以为了使 vue.js 兼容 CSP,它需要将所有 el.setAttribute('style', 'background-color:#e2e2e2; height: 24px; display:inline;') 替换为相应的集合:

    el.style.backgroundColor = '#e2e2e2';
    el.style.height = '24px';
    el.style.display = 'inline';
    
    1. 有一个 rough hack 可以做到这一点 - 当使用 'style' 参数调用它时,全局重新定义 setAttribute()

    2. 在将页面输出到浏览器之前,您可以在html代码中捕获并替换所有style='...'data-style='...',然后使用如下脚本:

      styleList = document.querySelectorAll("[data-style]");
      styleList.forEach( function(style) {
      // convert a 'background-color:#e2e2e2; height: 24px; display:inline;' strings
      // to the set of 'el.style.backgroundColor = '#e2e2e2'; ... el.style.display = 'inline';'&lt;br&gt; });`

    是的,这些是补丁,但是了解问题的本质,你或许能够找到更优雅的解决方案。

    【讨论】:

    • 感谢您的回答!如何使用 Vue 捕获和替换所有 style='...' 属性,在 HTML 输出到浏览器之前是否有类似钩子的东西可以捕获它?
    • 如果您使用VueJS Server-Side Rendering,这是可能的。例如,您可以使用 renderer.renderToString(app) 捕获 HTML:const html = await renderer.renderToString(app);
    • 但在这种情况下,您无法访问document 之类的内容,对吧?我在一个包含render:route Nuxt 钩子的 Nuxt 模块中尝试了这个。那个也能够捕捉到 HTML。但是我无法调用像 document.querySelectorAll("[data-style]"); 这样的东西,因为我是 SSR 上下文,这使得像 documentwindow 这样的东西不可用。我猜用VueJS Server Side Rendering也有同样的问题?
    • 是的,document 属性仅在浏览器中可用。在服务器端,您可以使用正则表达式之类的东西。
    猜你喜欢
    • 2023-04-03
    • 2021-12-26
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2016-03-25
    • 2013-10-09
    • 2015-07-28
    相关资源
    最近更新 更多