活动内容安全策略 (CSP) 和 Rails :back link

Active Content-Security-Policy (CSP) and Rails :back link

我想允许我的应用程序的内部 Rails :back link 功能与活动的内容安全策略。

CSP:

%meta{"http-equiv" => "Content-Security-Policy", "content" => "default-src *;"}

示例link:

= link_to 'Back', :back
# <a href="javascript:history.back()">Back</a> *

* Rails links to the referer and only if no referer is set falls back to JS.

我如何才能将 javascript 中的这一小块 history.back() 列入白名单?

我尝试按照 https://www.w3.org/TR/2015/CR-CSP2-20150721/#script-src-hash-usage 中的描述设置异常并生成所需的散列,如下所示:

echo -n "history.back()" | openssl dgst -sha256 -binary | openssl enc -base64

结果:

%meta{"http-equiv" => "Content-Security-Policy", "content" => "default-src *; script-src 'self' 'sha256-LdlORHyUW/rwezK0l13nW+IwcZmi78eWOCBjewMWRr4='"}

但是 Chrome 控制台显示相同的错误,这意味着散列无效:

Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-SmahML3R6+R4SRnsB6tEJ8Z4OVa4Qhk7A/gv3eAiG6s='". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

哈希白名单内联代码或内联样式无法使用活动的内容安全策略。上面的例子只有在 history.back() 是这样的脚本标签的内容时才有效:

<script>history.back()</script>

Chrome的错误信息具有误导性,因为它建议使用哈希方法将实际上不支持的内联代码列入白名单。

这同样适用于像 style="display:none" 这样的内联样式(例如在 nested_form gem 中使用)。

unsafe-inline 的使用不适合我的项目。因此,我通过猴子修补 class 或模块以使用不同的标记(例如 class="hidden")加上一些额外的外部 javascript 来解决这些罕见的问题,当然更新时也有缺点受影响 gems.

您还可以将 JS 移动到服务器上的外部文件中,并将其包含在 <script src=...> 中。您的 CSP 允许 *,因此也允许您自己的来源 ('self')。然后使用不显眼的 JavaScript 对 link 上的点击做出反应。思路如下:http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript