aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2022-02-25-relaxed-csp-for-go-coverage.md
blob: 20127ac0ed0644d7f51100c86e920d5a7e379ca5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
---
slug: relaxed-csp-for-go-coverage
title: "Relaxed Content-Security-Policy for Go Code Coverage Reports"
date: "2022-02-25T01:36:14-04:00"
---
There is a conflict between [my strict
`Content-Security-Policy`][my-csp] and the [CSS][] and [JavaScript][js]
embedded in the [HTML][] [code coverage][] reports generated by [`go
cover`][go-cover].

I tested a couple of methods of overriding the base
[`Content-Security-Policy`][csp], without success:

1. Add a relaxed [`<meta http-equiv='Content-Security-Policy'
   content='...'>`][meta-http-equiv] element.
2. Embed the script and style as [`data:` URLs][data-url].

(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:

```apache
#
# 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>
```
&nbsp;

The situation could be improved by making the following changes to the
[go cover HTML report source code][go-cover-html-src]:

1. Replace `style="display: none"` attribute on elements with
   `class=hide`.
2. Add `.hide { display: none }` to the inline `<style>` element.
2. Hash the inner content of the inline `<style>` element.
3. Hash the inner content of the inline `<script>` element.
4. Add a [`<meta http-equiv ...>`][meta-http-equiv] element to the
   header, using the hashes from the previous two steps.

Example:

```html
<meta
  http-equiv="content-security-policy"
  content="default-src 'self'; script-src 'self' 'sha256-a43KCehRqYcFBGPJxgYD6a15e6CRFwVvwuDAe8rGbkM='; style-src 'self' 'sha256-8OTC92xYkW7CWPJGhRvqCR0U1CR6L8PhhpRGGxgW4Ts='"
/>
```
&nbsp;

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.

[my-csp]: {{< ref "2021-10-25-the-nuclear-option-no-more-unsafe-inline" >}}
  "My strict Content-Security-Policy setting."
[go-cover]: https://go.dev/blog/cover
  "Go code coverage HTML reports."
[code coverage]: https://en.wikipedia.org/wiki/Code_coverage
  "Test suite code coverage."
[css]: https://en.wikipedia.org/wiki/CSS
  "Cascading Style Sheets"
[js]: https://en.wikipedia.org/wiki/JavaScript
  "JavaScript programming language."
[html]: https://en.wikipedia.org/wiki/HTML
  "HyperText Markup Language"
[meta-http-equiv]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
  "The <meta http-equiv ...> element."
[csp]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
  "Content-Security-Policy HTTP response header."
[data-url]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
  "Data URL."
[apache]: https://httpd.apache.org/
  "Apache web server."
[go-cover-html-src]: https://cs.opensource.google/go/go/+/master:src/cmd/cover/html.go;l=203
  "Template in source code for go cover HTML code coverage report."