对于 CSP header 避免 unsafe-inline,nonce 和 hash 之间哪个指令更好?
Which directive is better between nonce and hash for CSP header to avoid unsafe-inline?
我必须将 CSP header 添加到站点。问题是这是遗留代码,HTML 中有很多内联脚本和样式。我不能使用 'unsafe-inline',因为目的是实际确保站点安全,并且该指令在 OWASP ZAP 工具扫描中给出了红旗。我可以在一定程度上重构 HTML 和 JS 代码,但我有几个问题:
我已经尝试了固定随机数(仅用于 POC)和哈希方法来将内联脚本列入白名单。但是由于所有 HTML 都是静态的,我如何为每个请求向脚本标签添加一个新的随机数(随机数的实际情况是这样)?
在这种情况下,提供所有必需脚本和样式的哈希是否比随机数更好?
如果我重构所有 HTML 的代码以从 body 标记中删除所有内联脚本并将代码添加到 head 的单个脚本标记中,是否意味着内联脚本被淘汰了?简而言之,算作内联脚本吗?
- But since all the HTML is static how can I add a new nonce to the script tags for every request (as is the actual case for nonce)?
通常使用 'hash value'
,因为很难在每次重新加载页面时将 nonce="value"
属性动态插入到脚本和样式标签中。
然而,对于 Nginx 网络服务器,有一个使用服务器过滤器的解决方案(ngx_http_sub_module
或 ngx_http_substitutions_filter_module
)。
在静态 HTML 你使用一些“独特的字符串”:
<script nonce="@@=AAABBBCCCZZZ=@@"></script>
由服务器过滤器替换为服务器生成的值($request_id):
location / {
subs_filter @@=AAABBBCCCZZZ=@@ $request_id;
}
但这些模块可能默认没有内置到 Nginx 服务器中,您必须重新构建服务器。
- Is providing hash of all the required scripts and styles better than nonce for such case?
'hashe-value'
主要用于无法刷新 nonce
值的 SPA(单页应用程序)。但是,当您更改代码并需要用新的散列替换一些散列时,很难管理具有大量散列的 CSP。
因此在服务器端渲染的情况下,'nonce value'
的使用频率更高。此外 'nonce value'
不仅可以用于内联脚本,也可以用于外部脚本。
另请参阅下面关于 JS 框架的评论 - 这些框架可能与 'nonce-value'
或 'hash-value'
不兼容。
- If I refactor the code for all HTML to remove all the inline scripts from the body tag and add the code in a single script tag in head, does that mean that the inline scripts are eliminated?
否定。 CSP 不仅将 <script>
标记视为内联脚本,而且还将内置标记事件处理程序(如 <button onClick='...'>
和 javascript - 导航类 <a href='void(0)'>
.
还有一些 JS 框架,如 jQuery 需要强制性的 'unsafe-inline'
或 'unsafe-eval'
,并且可能与 'nonce-value'
或 'hash-value'
不兼容。
jQuery 自 v3.5.0 以来与 'nonce-value'
兼容。但是 jQuery 很难与 'hash-value'
兼容,因为动态生成主脚本并将其插入到 <head>
部分。
我必须将 CSP header 添加到站点。问题是这是遗留代码,HTML 中有很多内联脚本和样式。我不能使用 'unsafe-inline',因为目的是实际确保站点安全,并且该指令在 OWASP ZAP 工具扫描中给出了红旗。我可以在一定程度上重构 HTML 和 JS 代码,但我有几个问题:
我已经尝试了固定随机数(仅用于 POC)和哈希方法来将内联脚本列入白名单。但是由于所有 HTML 都是静态的,我如何为每个请求向脚本标签添加一个新的随机数(随机数的实际情况是这样)?
在这种情况下,提供所有必需脚本和样式的哈希是否比随机数更好?
如果我重构所有 HTML 的代码以从 body 标记中删除所有内联脚本并将代码添加到 head 的单个脚本标记中,是否意味着内联脚本被淘汰了?简而言之,算作内联脚本吗?
- But since all the HTML is static how can I add a new nonce to the script tags for every request (as is the actual case for nonce)?
通常使用 'hash value'
,因为很难在每次重新加载页面时将 nonce="value"
属性动态插入到脚本和样式标签中。
然而,对于 Nginx 网络服务器,有一个使用服务器过滤器的解决方案(ngx_http_sub_module
或 ngx_http_substitutions_filter_module
)。
在静态 HTML 你使用一些“独特的字符串”:
<script nonce="@@=AAABBBCCCZZZ=@@"></script>
由服务器过滤器替换为服务器生成的值($request_id):
location / {
subs_filter @@=AAABBBCCCZZZ=@@ $request_id;
}
但这些模块可能默认没有内置到 Nginx 服务器中,您必须重新构建服务器。
- Is providing hash of all the required scripts and styles better than nonce for such case?
'hashe-value'
主要用于无法刷新 nonce
值的 SPA(单页应用程序)。但是,当您更改代码并需要用新的散列替换一些散列时,很难管理具有大量散列的 CSP。
因此在服务器端渲染的情况下,'nonce value'
的使用频率更高。此外 'nonce value'
不仅可以用于内联脚本,也可以用于外部脚本。
另请参阅下面关于 JS 框架的评论 - 这些框架可能与 'nonce-value'
或 'hash-value'
不兼容。
- If I refactor the code for all HTML to remove all the inline scripts from the body tag and add the code in a single script tag in head, does that mean that the inline scripts are eliminated?
否定。 CSP 不仅将 <script>
标记视为内联脚本,而且还将内置标记事件处理程序(如 <button onClick='...'>
和 javascript - 导航类 <a href='void(0)'>
.
还有一些 JS 框架,如 jQuery 需要强制性的 'unsafe-inline'
或 'unsafe-eval'
,并且可能与 'nonce-value'
或 'hash-value'
不兼容。
jQuery 自 v3.5.0 以来与 'nonce-value'
兼容。但是 jQuery 很难与 'hash-value'
兼容,因为动态生成主脚本并将其插入到 <head>
部分。