From a4adbda5ef0981705f112c52b10be705932af80f Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 17 Oct 2018 14:46:31 +0200 Subject: [PATCH 1/4] Define parsing for X-Content-Type-Options in detail And add some of the infrastructure needed to define parsing better for all headers going forward (needed for #814). Fixes #752. This also fixes an issue with CORB as it simply assumed an X-Content-Type-Options was present. Tests: https://github.com/web-platform-tests/wpt/pull/13559. --- fetch.bs | 63 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/fetch.bs b/fetch.bs index c265d89b2..55ccf194a 100644 --- a/fetch.bs +++ b/fetch.bs @@ -300,6 +300,16 @@ specialized multimap. An ordered list of key-value pairs with potentially duplic (name) if list contains a header whose name is a byte-case-insensitive match for name. +

To get a name +name from a header list list, run these steps: + +

    +
  1. If list does not contain name, then return + null. + +

  2. Return the combined value with name and list. +

+

To append a name/value (name/value) pair to a header list (list), run these steps: @@ -368,7 +378,7 @@ a header list (list), run these steps:

For each name in names:

    -
  1. Let value be the combined value given name and +

  2. Let value be the combined value with name and list.

  3. Append name-value to headers. @@ -2498,7 +2508,32 @@ response header can be used to require checking of a respo `Content-Type` header against the destination of a request. -

    Its value ABNF: +

    To determine nosniff, given a header list list, run these +steps: + +

      +
    1. Let value be the result of getting + `X-Content-Type-Options` from list. + +

    2. If value is null, then return false. + +

    3. Let stringValue be the isomorphic encode of value. + +

    4. +

      Let tokens be the result of + Spliting stringValue on commas. + +

      This intentionally strips U+000C FORM FEED, despite 0x0C not being being a + HTTP whitespace byte. + +

    5. If tokens[0] is an ASCII case-insensitive match for + "nosniff", then return true. + +

    6. Return false. +

    + +

    Web developers and conformance checkers must use the following value +ABNF for `X-Content-Type-Options`:

     X-Content-Type-Options           = "nosniff" ; case-insensitive
    @@ -2510,16 +2545,8 @@ X-Content-Type-Options = "nosniff" ; case-insensitive

    Run these steps:

      -
    1. If response's header list - does not contain `X-Content-Type-Options`, - then return allowed. - -

    2. Let nosniff be the result of extracting header values from the - first header whose name is a byte-case-insensitive - match for `X-Content-Type-Options` in response's - header list. - -

    3. If nosniff is failure, then return allowed. +

    4. If determine nosniff with response's header list is + false, then return allowed.

    5. Let mimeType be the result of extracting a MIME type from response's header list. @@ -2578,14 +2605,10 @@ run these steps:

      mimeType (ignoring parameters) is a CORB-protected MIME type, then return blocked. -
    6. Let nosniff be the result of extracting header values from the - first header whose name is a byte-case-insensitive - match for `X-Content-Type-Options` in response's - header list. -

    7. -

      If nosniff is not failure and mimeType (ignoring parameters) is a - CORB-protected MIME type or text/plain, then return blocked. +

      If determine nosniff with response's header list is true + and mimeType (ignoring parameters) is a CORB-protected MIME type or + text/plain, then return blocked.

      CORB only protects text/plain responses with a `X-Content-Type-Options: nosniff` header. Unfortunately, protecting such responses @@ -4893,7 +4916,7 @@ invoked, must run these steps:

    8. If the context object's header list does not contain name, then return null. -

    9. Return the combined value given name and the +

    10. Return the combined value with name and the context object's header list.

    From d302e33b4e912d5f76f6545acf94ce514c816e50 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Thu, 18 Oct 2018 19:21:49 +0200 Subject: [PATCH 2/4] address part of the comments --- fetch.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fetch.bs b/fetch.bs index 55ccf194a..260e01fcc 100644 --- a/fetch.bs +++ b/fetch.bs @@ -2517,11 +2517,11 @@ steps:
  4. If value is null, then return false. -

  5. Let stringValue be the isomorphic encode of value. +

  6. Let stringValue be the isomorphic decode of value.

  7. Let tokens be the result of - Spliting stringValue on commas. + spliting stringValue on commas.

    This intentionally strips U+000C FORM FEED, despite 0x0C not being being a HTTP whitespace byte. From 81f14e3ac1a347d7a41b676009d568e757f4eb3b Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Tue, 30 Oct 2018 11:58:01 +0100 Subject: [PATCH 3/4] use "HTTP whitespace" --- fetch.bs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fetch.bs b/fetch.bs index 260e01fcc..68091830c 100644 --- a/fetch.bs +++ b/fetch.bs @@ -236,6 +236,11 @@ implementations can store the fragment nonetheless. borrows a number of concepts from HTTP and applies these to resources obtained via other means (e.g., data URLs). +

    HTTP whitespace is U+0009 TAB, U+000A LF, U+000D CR, or U+0020 SPACE. + +

    As opposed to ASCII whitespace this excludes U+000C FF. It is generally +preferable to use ASCII whitespace, except when defining parsers for HTTP header values. +

    The HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20.

    An HTTPS state value is "none", @@ -2519,14 +2524,13 @@ steps:

  8. Let stringValue be the isomorphic decode of value. -

  9. -

    Let tokens be the result of - spliting stringValue on commas. +

  10. Let tokens be the result of + strictly splitting stringValue on U+002C (,). -

    This intentionally strips U+000C FORM FEED, despite 0x0C not being being a - HTTP whitespace byte. +

  11. Let firstToken be the result of removing all HTTP whitespace from the + start and end of tokens[0]. -

  12. If tokens[0] is an ASCII case-insensitive match for +

  13. If firstToken is an ASCII case-insensitive match for "nosniff", then return true.

  14. Return false. From 3515d9bb72516098557e04a5d4131aad83f03c77 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Wed, 31 Oct 2018 10:14:10 +0100 Subject: [PATCH 4/4] be more precise about HTTP whitespace bytes --- fetch.bs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fetch.bs b/fetch.bs index 68091830c..f35be56a6 100644 --- a/fetch.bs +++ b/fetch.bs @@ -236,12 +236,14 @@ implementations can store the fragment nonetheless. borrows a number of concepts from HTTP and applies these to resources obtained via other means (e.g., data URLs). -

    HTTP whitespace is U+0009 TAB, U+000A LF, U+000D CR, or U+0020 SPACE. +

    An HTTP tab or space is U+0009 TAB or U+0020 SPACE. -

    As opposed to ASCII whitespace this excludes U+000C FF. It is generally -preferable to use ASCII whitespace, except when defining parsers for HTTP header values. +

    An HTTP newline byte is 0x0A (LF) or 0x0D (CR). -

    The HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20. +

    An HTTP tab or space byte is 0x09 (HT) or 0x20 (SP). + +

    An HTTP whitespace byte is an HTTP newline byte or +HTTP tab or space byte.

    An HTTPS state value is "none", "deprecated", or "modern". @@ -404,8 +406,8 @@ token production.

    A value is a byte sequence that matches the following conditions:

    The definition of value is not defined in terms of an HTTP token @@ -2527,7 +2529,7 @@ steps:

  15. Let tokens be the result of strictly splitting stringValue on U+002C (,). -

  16. Let firstToken be the result of removing all HTTP whitespace from the +

  17. Let firstToken be the result of removing all HTTP tab or space from the start and end of tokens[0].

  18. If firstToken is an ASCII case-insensitive match for @@ -6659,6 +6661,7 @@ Anssi Kostiainen, Arkadiusz Michalski, Arne Johannessen, Arthur Barstow, +Asanka Herath, Axel Rauschmayer, Ben Kelly, Benjamin Gruenbaum,