There is a conflict between my strict
Content-Security-Policy
and the CSS and JavaScript
embedded in the HTML code coverage reports generated by go cover
.
I tested a couple of methods of overriding the base
Content-Security-Policy
, without success:
- Add a relaxed
<meta http-equiv='Content-Security-Policy' content='...'>
element. - Embed the script and style as
data:
URLs.
(Aside: I’m glad browsers don’t allow these workarounds, because they would be potential security holes).
In any case, the my solution was to relax the policy for a specific location via the Apache config:
#
# Relax style-src and script-src content security policies for content
# in the "/coverage-reports" directory so that the HTML coverage reports
# generated by `go cover` work as expected.
#
# Specifically the relaxed constraints allow:
#
# 1. The inline `<script>` element at the end of the generated HTML.
# 2. `style='display: none'` attributes on hidden elements.
#
# Notes:
#
# * You *have* to use `Header set` rather than `Header append` to
# replace rather than append to the existing header.
# * Ideally we'd use `style-src-elem` and `script-src-elem`, but neither
# are currently supported by Firefox.
#
<Location /coverage-reports>
Header set "Content-Security-Policy" "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'"
</Location>
The situation could be improved by making the following changes to the go cover HTML report source code:
- Replace
style="display: none"
attribute on elements withclass=hide
. - Add
.hide { display: none }
to the inline<style>
element. - Hash the inner content of the inline
<style>
element. - Hash the inner content of the inline
<script>
element. - Add a
<meta http-equiv ...>
element to the header, using the hashes from the previous two steps.
Example:
<meta
http-equiv="content-security-policy"
content="default-src 'self'; script-src 'self' 'sha256-a43KCehRqYcFBGPJxgYD6a15e6CRFwVvwuDAe8rGbkM='; style-src 'self' 'sha256-8OTC92xYkW7CWPJGhRvqCR0U1CR6L8PhhpRGGxgW4Ts='"
/>
Bonus: These reports would automatically set a reasonable policy even in the absense of a more restrictive server policy.
Counter-argument to this post: These coverage reports are meant to be simple and only used locally. More elaborate or more secure coverage reports should be generated by a separate tool rather than complicating the default one.