Content-Security-Policy (CSP) parsing for invalid bytes in directives #48855
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The ABNF for CSP does not allow for characters outside of 0x21-0x7E (https://www.w3.org/TR/CSP3/#framework-directives).
Currently, browser behavior diverges for such cases.
I am not exactly sure what the correct behavior should be according to the specification. Chromium and Safari ignore the full directive if it contains an invalid byte, Firefox interprets the invalid byte as part of the directive value (effectively ignoring only this value as it is a meaningless value), another option would be to ignore the complete "header" or the complete "serialized policy". For some bytes such as NULL/\x00 other interpretations could be correct and currently exist.
For these tests I assumed that for \x00 network error should be the correct behavior (see whatwg/fetch#1156) and for all other cases that the directive should be ignored if they contain an invalid byte.
Implementation and test notes:
frame-ancestors 'self'|'none'
to check how the header is parsed/interpreted.frame-ancestors 'none'\x01
-> Directive ignored -> Framing allowed; Firefox behaves differentlyframe-ancestors 'none' http:\x01
-> Directive ignored -> Framing allowed; Firefox behaves differentlyframe-ancestors 'self'\x01
-> Directive ignored -> Framing allowed; Firefox behaves differentlyframe-ancestors 'none'; script-src 'self'\x01
-> Only script-src directive ignored -> Framing disallowedframe-ancestors 'self'; script-src 'self'\x01
-> Only script-src directive ignored -> Framing allowedframe-ancestors 'none', frame-ancestors 'self'\x01
-> Only the directive in the second policy is ignored -> Framing disallowedframe-ancestors 'none', frame-ancestors\x01
-> Only the second directive is ignored -> Framing disallowedframe-ancestors 'self', frame-ancestors\x01
-> Only the second directive is ignored -> Framing allowednet::ERR_INVALID_HTTP_RESPONSE
) and displays error frames (chrome-error://chromewebdata/
)NS_ERROR_DOM_INVALID_HEADER_VALUE
). However, the frame stays completely empty. No child-document such as error frame or about:blank or similar is added to the DOM. Thus, all tests timeout asev.target.contentDocument.readyState !== "complete"
is never falseFailed to load resource: Response contained invalid HTTP headers
). For the other 3 tests (e.g.,frame-ancestors 'none'; script-src 'self'\x00
), the frame is blocked due to CSP and not due to the network error, seems like the CSP decisions comes before the network error decision (which seems strange). The 6 tests that throw a network error also timeout, because anabout:blank
iframe is added which is not detected (https://github.com/JannisBush/wpt/blob/patch-7/content-security-policy/parsing/support/helper.sub.js#L63)See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1891465