CSP header 的 nonce 和 hash 之间哪个指令更好,以避免不安全内联?

Hri*_*ane 4 javascript inline-scripting content-security-policy

我必须将 CSP 标头添加到站点。问题是这是一个遗留代码,并且 HTML 中有很多内联脚本和样式。我无法使用“unsafe-inline”,因为目的是真正确保站点安全,并且该指令在 OWASP ZAP 工具扫描中给出了危险信号。我可以在某种程度上重构 HTML 和 JS 代码,但我有几个问题:

  1. 我尝试过使用固定随机数(仅适用于 POC)和哈希方式将内联脚本列入白名单。但由于所有 HTML 都是静态的,我如何为每个请求的脚本标记添加新的随机数(随机数的实际情况就是如此)?

  2. 在这种情况下,提供所有必需脚本和样式的哈希值是否比随机数更好?

  3. 如果我重构所有 HTML 的代码以从 body 标记中删除所有内联脚本并将代码添加到 head 中的单个脚本标记中,这是否意味着内联脚本被消除了?简而言之,in算作内联脚本吗?

gra*_*nty 5

  1. 但由于所有 HTML都是静态的,我如何为每个请求的脚本标记添加新的随机数(随机数的实际情况就是如此)?

A是常用的,因为每次重新加载页面时'hash value'很难将属性动态插入到脚本和样式标记中。 然而,对于 Nginx Web 服务器,有一个使用服务器过滤器(或)的解决方案。 在静态 HTML 中,您使用一些“唯一字符串”:nonce="value"
ngx_http_sub_modulengx_http_substitutions_filter_module

<script nonce="@@=AAABBBCCCZZZ=@@"></script>
Run Code Online (Sandbox Code Playgroud)

它被服务器的过滤器替换为服务器生成的值($request_id):

location / {
    subs_filter @@=AAABBBCCCZZZ=@@ $request_id;
    }
Run Code Online (Sandbox Code Playgroud)

但是这些模块默认情况下可能没有内置到Nginx服务器中,你必须重建服务器。

  1. 在这种情况下,提供所有必需脚本和样式的哈希值是否比随机数更好?

主要用于'hashe-value'SPA(单页应用程序),您无法刷新nonce价值。但是,当您更改代码并需要用新的哈希值替换一些哈希值时,很难管理具有大量哈希值的 CSP。

因此,在服务端渲染的情况下,'nonce value'更常使用。此外,'nonce value'不仅可以用于内联脚本,还可以用于外部脚本。

另请参阅下面有关 JS 框架的评论 - 这些框架可能与'nonce-value'或 不兼容'hash-value'

  1. 如果我重构所有 HTML 的代码以从 body 标记中删除所有内联脚本并将代码添加到 head 中的单个脚本标记中,这是否意味着内联脚本被消除了?

消极的。CSP 不仅将<script>标签视为内联脚本,还将内置标签事件处理程序(如<button onClick='...'>javascript-navigation 之类的)视为内联脚本<a href='void(0)'>

此外,一些 JS 框架(例如 jQuery)需要强制使用'unsafe-inline'or ,'unsafe-eval'并且可能与'nonce-value'or不兼容'hash-value'。jQuery自v3.5.0
起 兼容。但 jQuery 几乎不兼容,因为动态生成主脚本并将其插入到部分中。'nonce-value''hash-value'<head>