New issue
Advanced search Search tips

Issue 596267 link

Starred by 1 user

Issue metadata

Status: Duplicate
Merged: issue 611652
Owner: ----
Closed: Jul 2016
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

CSP report only policy enforced in place of CSP's when returning BOTH http response headers and when a nonce is used as a script-src

Reported by thiba...@intercom.io, Mar 19 2016

Issue description

Chrome Version       : 49.0.2623.87 (Official Build) (64-bit)
URLs (if applicable) : N/A
Other browsers tested: N/A

PROBLEM:

Adding an extra ‘content-security-policy-report-only’ header to a response already containing a ‘content-security-policy’ header messes up the processing and enforcement of the later when nonces are used as script-src.

BACKGROUND:
As indicated below, I’m using a CSP-only header to tighten a currently deployed CSP policy: 
https://developers.google.com/web/fundamentals/security/csp/reporting?hl=en
“You can even send both headers, enforcing one policy while monitoring another. This is a great way to evaluate the effect of changes to your application’s CSP: turn on reporting for a new policy, monitor the violation reports and fix any bugs that turn up, then start enforcing the new policy once you’re satisfied with its effect.”

Assuming this page (https://localhost:4443/index.html):

<html>
<body>
<script nonce="2726c7f26c">
alert(123);
</script>
<img src="http://www.catsaid.ie/wp-content/uploads/2015/05/Zoe.jpg" />
</body>
</html>

TEST 1 (PASS) - only inject a CSP header:
content-security-policy: default-src 'self'; img-src 'self' data: blob: https: http:; script-src 'nonce-2726c7f26c'

is rendered OK, the console flags a warning “Mixed Content: The page at 'https://localhost:4443/index.html' was loaded over HTTPS, but requested an insecure image 'http://www.catsaid.ie/wp-content/uploads/2015/05/Zoe.jpg'. This content should also be served over HTTPS.”

TEST 2 (PASS) - only injecting a CSP-REPORT-ONLY header :
content-security-policy-report-only:default-src 'self'; connect-src *; font-src * data: blob:; frame-src *; img-src 'self' data: blob: https:; media-src *; object-src *; script-src *; style-src * 'unsafe-inline'; report-uri https://test.com

is rendered OK, the console flags a warning “Mixed Content: The page at 'https://localhost:4443/index.html' was loaded over HTTPS, but requested an insecure image 'http://www.catsaid.ie/wp-content/uploads/2015/05/Zoe.jpg'. This content should also be served over HTTPS.” and 2 CSP-REPORT-ONLY errors:

a) [Report Only] Refused to execute inline script because it violates the following Content Security Policy directive: "script-src *". Either the 'unsafe-inline' keyword, a hash ('sha256-XnNxFLd7d8ScH4qanWNBnaI3GEaJC0LJ+znnIsfo648='), or a nonce ('nonce-...') is required to enable inline execution.

b) [Report Only] Refused to load the image 'http://www.catsaid.ie/wp-content/uploads/2015/05/Zoe.jpg' because it violates the following Content Security Policy directive: "img-src 'self' data: blob: https:".

I don’t quite understand why a) fires (script-src * should cover this) but b) makes sense.

TEST 3 (FAIL) - inject both headers:
content-security-policy: default-src 'self'; img-src 'self' data: blob: https: http:; script-src 'nonce-2726c7f26c'
content-security-policy-report-only:default-src 'self'; connect-src *; font-src * data: blob:; frame-src *; img-src 'self' data: blob: https:; media-src *; object-src *; script-src *; style-src * 'unsafe-inline'; report-uri https://test.com

is NOT rendered OK, the console flags a warning “Mixed Content: The page at 'https://localhost:4443/index.html' was loaded over HTTPS, but requested an insecure image 'http://www.catsaid.ie/wp-content/uploads/2015/05/Zoe.jpg'. This content should also be served over HTTPS.” and 2 errors (one CSP, one CSP-REPORT-ONLY):

a) Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-2726c7f26c'". Either the 'unsafe-inline' keyword, a hash ('sha256-XnNxFLd7d8ScH4qanWNBnaI3GEaJC0LJ+znnIsfo648='), or a nonce ('nonce-...') is required to enable inline execution.

b) [Report Only] Refused to load the image 'http://www.catsaid.ie/wp-content/uploads/2015/05/Zoe.jpg' because it violates the following Content Security Policy directive: "img-src 'self' data: blob: https:".

a) should not block as we’ve verified earlier in TEST 1. 
b) makes sense

SUMMARY
It seems like the CSP-REPORT-ONLY header’s policy is enforced in place of the CSP header’s.

Also, it seems that ‘script-src *’ does not cover cases where a nonce is used.

 
Actually scratch that: in fact, it seems like the loading the mixed content is not a requirement for this bug to reproduce. Also, replacing script-src * by script-src 'unsafe-inline' makes all this clearer:

RETURNED PAYLOAD:

<html>
<body>
<script nonce="2726c7f26c">
alert(123);
</script>
</body>
</html>

TEST 1 (PASS) - only inject a CSP header:
content-security-policy: default-src 'self'; img-src 'self' data: blob: https: http:; script-src 'nonce-2726c7f26c'
RESULT: The JS runs.

TEST 2 (PASS)- only injecting a CSP-REPORT-ONLY header :
content-security-policy-report-only:default-src 'self'; connect-src *; font-src * data: blob:; frame-src *; img-src 'self' data: blob: https:; media-src *; object-src *; script-src 'unsafe-inline'; style-src * 'unsafe-inline'; report-uri https://test.com
RESULT: The JS runs.

TEST 3 (FAIL) - inject both headers:
content-security-policy: default-src 'self'; img-src 'self' data: blob: https: http:; script-src 'nonce-2726c7f26c'
content-security-policy-report-only:default-src 'self'; connect-src *; font-src * data: blob:; frame-src *; img-src 'self' data: blob: https:; media-src *; object-src *; script-src 'unsafe-inline'; style-src * 'unsafe-inline'; report-uri https://test.com
RESULT: The JS does NOT run and a CSP error is logged in the console:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-2726c7f26c'". Either the 'unsafe-inline' keyword, a hash ('sha256-XnNxFLd7d8ScH4qanWNBnaI3GEaJC0LJ+znnIsfo648='), or a nonce ('nonce-...') is required to enable inline execution.

PROBLEM
There is no reason why this error should be fired.
Labels: Te-NeedsFurtherTriage
Do you need more info, more detailed repro steps, more explanations as to why this is a bug?

Comment 4 by shek...@gmail.com, Apr 1 2016

Looks like a problem to me. Here is simplified example:
```
package main

import (
    "fmt"
    "net/http"
)
func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Security-Policy", "script-src 'nonce-123'")
        w.Header().Set("Content-Security-Policy-Report-Only", "script-src 'nonce-345'")
    fmt.Fprintln(w, `<html>
    <body>
      <script nonce='123'>alert(1)</script>
    </body>
  </html>`)
    })
    http.ListenAndServe(":8888", nil)
}
```

script should not be blocked
Components: Blink>SecurityFeature
shekyan from comment 4, could you please specify what version of Chrome you're testing on? This looks like it could be a duplicate of  issue 503730  which should be fixed in Canary.
Mergedinto: 611652
Status: Duplicate (was: Unconfirmed)
Yeah, I confirmed this is fixed in Canary. It's not a duplicate of the issue I mentioned but is a duplicate of  issue 611652 . Thanks for the report!

Sign in to add a comment