内容安全策略随机数不适用于事件处理程序属性

时间:2019-05-31 18:04:04

标签: javascript content-security-policy nonce

我正在将CSP标头添加到要采用严格策略之前还有很长的路要走的网站。有很多内联脚本,因此我使用nonce-来允许特定的内联脚本。我发现它不适用于src的脚本标签的onload属性。这是一个示例:

// header:
Content-Security-Policy: script-src self https: 'nonce-d3adbe3fed'

<script async defer src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js" nonce="d3adbe3fed" onload="console.log('onload', _.VERSION)"></script>

https://brave-pasteur-0d438b.netlify.com/上的完整演示程序

Chrome出现以下错误:

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src self https: 'nonce-d3adbe3fed'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

该消息表明应该可以使用随机数启用内联事件处理程序,但是据我所知,随机数仅适用于内联脚本。

这只是一个演示,但用例是一个异步/延迟跟踪脚本,该脚本加载了跟踪库,然后在onload处理程序中对已加载的库进行了跟踪调用。

是否可以在onload或其他事件处理程序属性上使用随机数,还是需要更改实现?不能选择使用script-src 'unsafe-inline'script-src-attr 'unsafe-inline',因为这些是我专门尝试解决的漏洞。另外,也不能选择将onload处理程序的内容放在script标记之后的单独脚本中,因为该脚本是async deferred,并且需要保持这种状态。

1 个答案:

答案 0 :(得分:1)

如果可以在内联处理程序上使用nonce,我将接受一个演示它的答案。不幸的是,在撰写本文时,我认为还没有。

作为一种解决方法,以下脚本在满足指定的CSP策略的同时,其行为和计时与具有异步/延迟和onload处理程序的脚本相同:

<script nonce="d3adbe3fed">
    let s = document.createElement('script');
    s.src = 'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js';
    s.onload = () => console.log(_.VERSION);
    document.documentElement.appendChild(s);
</script>

当然,长期的解决方案是完全消除内联脚本,但短期内这并不总是可行的,并且快速实施更宽松的策略比放开它并没有CSP更好。完全没有。