Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

80%
+6 −0
Q&A Why does Firefox block based on a restrictive default-src directive, when more specific, more permissive *-src exist?

Each header is checked independently Having multiple Content Security Policy headers can only make it more restrictive I assume that each Content-Security-Policy: line you have is a separate CSP ...

posted 2y ago by Moshi‭  ·  edited 2y ago by Moshi‭

Answer
#2: Post edited by user avatar Moshi‭ · 2021-08-02T18:47:51Z (over 2 years ago)
Added solution, touched up a bit
  • ## Each header is checked independently
  • [Having multiple Content Security Policy headers can only make it more restrictive ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#multiple_content_security_policies)
  • I assume that each `Content-Security-Policy:` line you have is a separate CSP header. If you send each separately, then a source will be checked on each CSP separately.
  • Taking your inline style, we first check the first header.
  • ```http
  • Content-Security-Policy: style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/;
  • ```
  • All good here, we have 'unsafe-inline'. The problem come at the last header.
  • ```http
  • Content-Security-Policy: default-src 'self';
  • ```
  • This header doesn't have `style-src`, so it checks `default-src` which only allows 'self', and so it blocks it, throwing the error that you got.
  • ### W3C Specification
  • [The level 3 specification states](https://w3c.github.io/webappsec-csp/#csp-header)
  • > When the user agent receives a Content-Security-Policy header field, it MUST [parse](https://w3c.github.io/webappsec-csp/#abstract-opdef-parse-a-serialized-csp) and [enforce](https://w3c.github.io/webappsec-csp/#enforced) each serialized CSP it contains as described in § 4.1 Integration with Fetch, § 4.2 Integration with HTML.
  • The important part of this is that parsing results in a new, independent policy being created for each header. Enforcing just means inserting that new policy into the global CSP list.
  • Digging a bit deeper, we find [Should request be blocked by Content Security Policy?](https://w3c.github.io/webappsec-csp/#should-block-request)
  • > 1. Let CSP list be request’s policy container's CSP list.
  • > 2. Let result be "Allowed".
  • > 3. For each policy in CSP list:
  • > 1. If policy’s disposition is "report", then skip to the next policy.
  • > 2. Let violates be the result of executing § 6.6.2.1 Does request violate policy? on request and policy.
  • > 3. If violates is not "Does Not Violate", then:
  • > 1. Execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request, and policy.
  • > 2. Set result to "Blocked".
  • > 4. Return result.
  • As you can see, each policy is evaluated independently, and a request has to pass all of them. Since each header creates a new policy, this means that sending multiple headers will only further restrict the requests that pass.
  • ## Each header is checked independently
  • [Having multiple Content Security Policy headers can only make it more restrictive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#multiple_content_security_policies)
  • I assume that each `Content-Security-Policy:` line you have is a separate CSP header. If you send each separately, then a source will be checked on each CSP separately.
  • For example, the way your inline style is checked is we first check the first policy.
  • ```http
  • Content-Security-Policy: style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/;
  • ```
  • All good here, we have 'unsafe-inline'. The problem comes at the last header.
  • ```http
  • Content-Security-Policy: default-src 'self';
  • ```
  • This header doesn't have `style-src`, so it checks `default-src` which only allows 'self', and so it blocks it, throwing the error that you got.
  • ### Solution: Put all the policies in one header
  • ```http
  • Content-Security-Policy:
  • style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/;
  • font-src 'self' https://fonts.gstatic.com/;
  • default-src 'self';
  • ```
  • ### W3C Specification
  • [The level 3 specification states](https://w3c.github.io/webappsec-csp/#csp-header)
  • > When the user agent receives a Content-Security-Policy header field, it MUST [parse](https://w3c.github.io/webappsec-csp/#abstract-opdef-parse-a-serialized-csp) and [enforce](https://w3c.github.io/webappsec-csp/#enforced) each serialized CSP it contains as described in § 4.1 Integration with Fetch, § 4.2 Integration with HTML.
  • The important part of this is that parsing results in a new, independent policy being created for each header. Enforcing just means inserting that new policy into the global CSP list.
  • Digging a bit deeper, we find the algorithm used to determine if a request should be blocked: [Should request be blocked by Content Security Policy?](https://w3c.github.io/webappsec-csp/#should-block-request)
  • > 1. Let CSP list be request’s policy container's CSP list.
  • > 2. Let result be "Allowed".
  • > 3. For each policy in CSP list:
  • > 1. If policy’s disposition is "report", then skip to the next policy.
  • > 2. Let violates be the result of executing § 6.6.2.1 Does request violate policy? on request and policy.
  • > 3. If violates is not "Does Not Violate", then:
  • > 1. Execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request, and policy.
  • > 2. Set result to "Blocked".
  • > 4. Return result.
  • As you can see, each policy is evaluated independently, and a request must pass all of them. Since each header creates a new policy, this means that sending multiple headers will only further restrict the requests that pass.
#1: Initial revision by user avatar Moshi‭ · 2021-08-02T09:55:37Z (over 2 years ago)
## Each header is checked independently

[Having multiple Content Security Policy headers can only make it more restrictive ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#multiple_content_security_policies)

I assume that each `Content-Security-Policy:` line you have is a separate CSP header. If you send each separately, then a source will be checked on each CSP separately.

Taking your inline style, we first check the first header.

```http
Content-Security-Policy: style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/;
```

All good here, we have 'unsafe-inline'. The problem come at the last header. 

```http
Content-Security-Policy: default-src 'self';
```

This header doesn't have `style-src`, so it checks `default-src` which only allows 'self', and so it blocks it, throwing the error that you got. 

### W3C Specification

[The level 3 specification states](https://w3c.github.io/webappsec-csp/#csp-header) 

> When the user agent receives a Content-Security-Policy header field, it MUST [parse](https://w3c.github.io/webappsec-csp/#abstract-opdef-parse-a-serialized-csp) and [enforce](https://w3c.github.io/webappsec-csp/#enforced) each serialized CSP it contains as described in § 4.1 Integration with Fetch, § 4.2 Integration with HTML.

The important part of this is that parsing results in a new, independent policy being created for each header. Enforcing just means inserting that new policy into the global CSP list. 

Digging a bit deeper, we find [Should request be blocked by Content Security Policy?](https://w3c.github.io/webappsec-csp/#should-block-request) 

> 1. Let CSP list be request’s policy container's CSP list.
> 2. Let result be "Allowed".
> 3. For each policy in CSP list:
>    1. If policy’s disposition is "report", then skip to the next policy.
>    2. Let violates be the result of executing § 6.6.2.1 Does request violate policy? on request and policy.
>    3. If violates is not "Does Not Violate", then:
>       1. Execute § 5.3 Report a violation on the result of executing § 2.4.2 Create a violation object for request, and policy. on request, and policy.
>       2. Set result to "Blocked".
> 4. Return result. 

As you can see, each policy is evaluated independently, and a request has to pass all of them. Since each header creates a new policy, this means that sending multiple headers will only further restrict the requests that pass.