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

Tests for HTTP/1.1 Parsing (NUL, CR, LF, Colon and more) #50629

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

Conversation

JannisBush
Copy link
Contributor

Parsing (invalid) HTTP/1.1 responses is not fully defined in HTTP and Fetch and browser behavior diverges from the specs and between different browsers and there are not many tests in WPT yet. The aim of this pull request is to document the current browser behavior for various edge cases and start standardizing edge case behavior.

This pull requests adds a bunch of tests for (invalid) HTTP/1.1 responses for various edge cases. The tests are marked as tentative.
The tests are about the general parsing of (invalid) HTTP/1.1 messages and are not about the parsing of individual (invalid) headers such as how browsers should handle invalid bytes in CSP headers (Pull Request for that here).

All tests use the following base response and inject various bytes in different places to test both status-line and header-line parsing.
There are two types of tests:

  • fetch tests: they fetch the resource and either fail (Network Error) or fetch the resource (Valid)
  • framing tests: they frame the resource in an IFrame. They can result in Network Error (browser renders an error frame), active-XFO (browser renders an error frame due to XFO), or render the iframe (no-XFO, either the value is invalid or the full header line containing XFO is ignored). Note that the tests currently do not distinguish between Network Error and active-XFO.
HTTP/1.1 200 OK
X-Frame-Options: DENY
Content-Length: 5

Test.

The following shows all the injection points and their names:

<first>HT<in-http>TP<before-slash>/<after-slash>1<before-dot>.<after-dot>1<after-ver> <before-num>200<after-num> <before-reason>OK<after-reason>
<leading>X-Frame<in-name>-Options<before-colon>:<after-colon>DE<in-value>NY<after-value>
Content-Length: 5

Test.

The following bytes are injected: LF, CR, HTAB, SP, NUL, COLON.

The expected behavior is described in a mapping:

let expected = {
    "SP": {
        "first": ["Network Error", "Network Error"],
        ...
        "in-value": ["Valid", "no-XFO"],
        "after-value": ["Valid", "active-XFO"]
    },
    ...
}

Currently, there are 102*2=204 tests. In the future, other characters could be injected or other tests can be added.
The initial expected mapping is strict and expects "Network Error" for almost everything that is not explicitly allowed.
The current results are (both on HTTP and HTTPS):

  • Chrome: 114 Pass, 90 Fail
  • Firefox: 61 Pass, 143 Fail
  • Safari: 92 Pass, 112 Fail

See also:

Copy link
Contributor

@jdm jdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very thorough! I appreciate all of the clear explanations for the expected results.

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

Successfully merging this pull request may close these issues.

4 participants