Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content-Security-Policy (CSP) parsing for invalid bytes in directives #48855

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

JannisBush
Copy link
Contributor

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:

  • I used frame-ancestors 'self'|'none' to check how the header is parsed/interpreted.
  • All non-NULL invalid bytes (examples used: \x01 and \x7f)
    • frame-ancestors 'none'\x01 -> Directive ignored -> Framing allowed; Firefox behaves differently
    • frame-ancestors 'none' http:\x01 -> Directive ignored -> Framing allowed; Firefox behaves differently
    • frame-ancestors 'self'\x01 -> Directive ignored -> Framing allowed; Firefox behaves differently
    • frame-ancestors 'none'; script-src 'self'\x01 -> Only script-src directive ignored -> Framing disallowed
    • frame-ancestors 'self'; script-src 'self'\x01 -> Only script-src directive ignored -> Framing allowed
    • `frame-ancestors 'self', frame-ancestors 'self'\x01 -> Only the directive in the second policy is ignored -> Framing allowed; Firefox behaves differently
    • frame-ancestors 'none', frame-ancestors 'self'\x01 -> Only the directive in the second policy is ignored -> Framing disallowed
    • frame-ancestors 'none', frame-ancestors\x01 -> Only the second directive is ignored -> Framing disallowed
    • frame-ancestors 'self', frame-ancestors\x01 -> Only the second directive is ignored -> Framing allowed
  • NULL/\x00
    • The correct result should be network error (see HTTP/1 parsing whatwg/fetch#1156)
    • Chromium throws network errors for all of them (net::ERR_INVALID_HTTP_RESPONSE) and displays error frames (chrome-error://chromewebdata/)
    • Firefox throws network errors for all of them (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 as ev.target.contentDocument.readyState !== "complete" is never false
    • Safari only throws network errors for 6 out of the 9 tests (Failed 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 an about: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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants