ToniTornado ToniTornado - 4 months ago 7
Javascript Question

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

I want to allow the internal Rails :back link functionality for my application with an active Content-Security-Policy.

CSP:

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


Example 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.


How can I whitelist only this tiny
history.back()
piece of javascript?

I tried to set an exception as described in https://www.w3.org/TR/2015/CR-CSP2-20150721/#script-src-hash-usage and generated the required hash like this:

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


Result:

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


But the Chrome console displays the same error what means the hash is invalid:


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.

Answer

Hash-whitelisting inline code oder inline styles is not possible with an active Content Security Policy. The above example would only work if history.back() was the content of a script-tag like this:

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

Chrome's error message is misleading, because it suggests using the hash method for whitelisting the inline code which is actually not supported.

The same applies for inline styles like style="display:none" (used for example in nested_form gem).

The use of unsafe-inline was no option for my project. So I solved these rare problems by monkey patching the class or module to use different markup (for example class="hidden") plus some additional external javascript where required but of course there are drawbacks when updating the affected gems.