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
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 ...
Answer
#2: Post edited
- ## 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
## 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.