Repository: gratipay/gratipay.com

Issue:
Localhost not loading in Firefox
Just found this problem in Firefox while setting up Gratipay locally on @dmk246 laptop. For some reason the page never loads when you `make run` and try to open localhost:8537 in Firefox it hangs. We believe it is because `gratipay.report_uri.io` 


Discussion:
Indeed.

![screen shot 2017-02-16 at 1 34 35 pm](https://cloud.githubusercontent.com/assets/134455/23035321/ab821156-f44c-11e6-995b-49716ed4ec74.png)

Why do we have a CSP violation in stock Gratipay?

![screen shot 2017-03-24 at 11 06 05 am](https://cloud.githubusercontent.com/assets/134455/24300167/edae5a34-1081-11e7-99b2-d4faea310637.png)

Chrome also recognizes violations. Presumably their implementation precludes blocking on same.

![screen shot 2017-03-24 at 11 12 34 am](https://cloud.githubusercontent.com/assets/134455/24300428/cd8c3522-1082-11e7-8c38-ad8de8dc780d.png)

> The Content Security Policy directive 'upgrade-insecure-requests' is ignored when delivered in a report-only policy.

The `upgrade-insecure-requests` directive is ignored when sent via a `Content-Security-Policy-Report-Only` header: https://www.w3.org/TR/upgrade-insecure-requests/#delivery

> Unrecognized Content-Security-Policy directive 'reflected-xss'.

The `reflected-xss` directive has been deprecated in Chrome 56+: https://www.chromestatus.com/feature/5769374145183744

> Refused to apply inline style because it violates the following Content Security Policy directive: [...]

```html
<a class="github-ribbon" href="https://github.com/gratipay/gratipay.com">
   <img style="position: absolute; top: 0; right: 0; border: 0;"
      src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"
      alt="Fork me on GitHub">
</a>
```
Ah! So *that's* what @nobodxbodon was [on about](https://github.com/gratipay/gratipay.com/issues/4359#issuecomment-287519144). :D
Yep. We must remove the inline style attribute from the GitHub banner.
Okay, I did that and the CSP error is gone, but FF is still spinning, and any other request even from another browser also blocks until I cancel the FF request. :thinking:

![screen shot 2017-03-24 at 11 32 33 am](https://cloud.githubusercontent.com/assets/134455/24301309/aed769a0-1085-11e7-8e3c-b736ca0bff4d.png)

> The upgrade-insecure-requests directive is evaluated before block-all-mixed-content and if it is set, the latter is effectively a no-op. **It is recommended to set one directive or the other, but not both.** [[Source]]

Whoops!

```
"upgrade-insecure-requests;"
"block-all-mixed-content;"
```
Link to source code: https://github.com/gratipay/gratipay.com/blob/master/gratipay/security/__init__.py#L56-L57

[Source]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests
Yeah, okay. I was just dialing in on `upgrade-insecure-requests` as the culprit.
Whittled down to the base page + one asset which should've been 404 but was still triggering tailspin.

![screen shot 2017-03-24 at 11 41 16 am](https://cloud.githubusercontent.com/assets/134455/24301781/dd5e8636-1086-11e7-87f7-1a415d9c71f5.png)

Okay! Root cause! Fix?
PR on the way!

Resolving patch:
diff --git a/gratipay/security/__init__.py b/gratipay/security/__init__.py
--- a/gratipay/security/__init__.py
+++ b/gratipay/security/__init__.py
@@ -43,7 +43,8 @@ def add_headers_to_response(response):
 
     # https://www.w3.org/TR/referrer-policy/
     if 'Referrer-Policy' not in response.headers:
-        response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
+        response.headers['Referrer-Policy'] = \
+                                      'no-referrer-when-downgrade, strict-origin-when-cross-origin'
 
     # https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
     if 'content-security-policy-report-only' not in response.headers:
@@ -53,8 +54,6 @@ def add_headers_to_response(response):
             "style-src 'self' assets.gratipay.com downloads.gratipay.com cloud.typography.com;"
             "img-src *;"
             "font-src 'self' assets.gratipay.com cloud.typography.com data:;"
-            "upgrade-insecure-requests;"
             "block-all-mixed-content;"
-            "reflected-xss block;"
             "report-uri https://gratipay.report-uri.io/r/default/csp/reportOnly;"
         )


Test patch:
diff --git a/tests/py/test_security.py b/tests/py/test_security.py
--- a/tests/py/test_security.py
+++ b/tests/py/test_security.py
@@ -55,7 +55,8 @@ def test_ahtr_sets_x_xss_protection(self):
 
     def test_ahtr_sets_referrer_policy(self):
         headers = self.client.GET('/about/').headers
-        assert headers['Referrer-Policy'] == 'strict-origin-when-cross-origin'
+        assert headers['Referrer-Policy'] == \
+                                      'no-referrer-when-downgrade, strict-origin-when-cross-origin'
 
     def test_ahtr_sets_content_security_policy(self):
         headers = self.client.GET('/about/').headers
@@ -65,9 +66,7 @@ def test_ahtr_sets_content_security_policy(self):
             "style-src 'self' assets.gratipay.com downloads.gratipay.com cloud.typography.com;"
             "img-src *;"
             "font-src 'self' assets.gratipay.com cloud.typography.com data:;"
-            "upgrade-insecure-requests;"
             "block-all-mixed-content;"
-            "reflected-xss block;"
             "report-uri https://gratipay.report-uri.io/r/default/csp/reportOnly;"
         )
         assert headers['content-security-policy-report-only'] == policy