Skip to content

Commit 32c7b1c

Browse files
authored
Define parsing for X-Content-Type-Options: nosniff 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: web-platform-tests/wpt#13559.
1 parent 7b882d1 commit 32c7b1c

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

fetch.bs

+53-23
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,14 @@ implementations can store the <a for=url>fragment</a> nonetheless.
236236
borrows a number of concepts from HTTP and applies these to resources obtained via other
237237
means (e.g., <code>data</code> URLs).
238238

239-
<p>The <dfn export>HTTP whitespace bytes</dfn> are 0x09, 0x0A, 0x0D, and 0x20.
239+
<p>An <dfn export>HTTP tab or space</dfn> is U+0009 TAB or U+0020 SPACE.
240+
241+
<p>An <dfn export>HTTP newline byte</dfn> is 0x0A (LF) or 0x0D (CR).
242+
243+
<p>An <dfn export>HTTP tab or space byte</dfn> is 0x09 (HT) or 0x20 (SP).
244+
245+
<p>An <dfn export>HTTP whitespace byte</dfn> is an <a>HTTP newline byte</a> or
246+
<a>HTTP tab or space byte</a>.
240247

241248
<p>An <dfn export id=concept-https-state-value>HTTPS state value</dfn> is "<code>none</code>",
242249
"<code>deprecated</code>", or "<code>modern</code>".
@@ -300,6 +307,16 @@ specialized multimap. An ordered list of key-value pairs with potentially duplic
300307
(<var>name</var>) if <var>list</var> <a for=list>contains</a> a <a for=/>header</a> whose
301308
<a for=header>name</a> is a <a>byte-case-insensitive</a> match for <var>name</var>.
302309

310+
<p>To <dfn export for="header list" id=concept-header-list-get>get</dfn> a <a for=header>name</a>
311+
<var>name</var> from a <a for=/>header list</a> <var>list</var>, run these steps:
312+
313+
<ol>
314+
<li><p>If <var>list</var> <a for="header list">does not contain</a> <var>name</var>, then return
315+
null.
316+
317+
<li><p>Return the <a for="header">combined value</a> with <var>name</var> and <var>list</var>.
318+
</ol>
319+
303320
<p>To <dfn export for="header list" id=concept-header-list-append>append</dfn> a
304321
<a for=header>name</a>/<a for=header>value</a> (<var>name</var>/<var>value</var>) pair to a
305322
<a for=/>header list</a> (<var>list</var>), run these steps:
@@ -368,7 +385,7 @@ a <a for=/>header list</a> (<var>list</var>), run these steps:
368385
<p><a for=list>For each</a> <var>name</var> in <var>names</var>:
369386

370387
<ol>
371-
<li><p>Let <var>value</var> be the <a for=header>combined value</a> given <var>name</var> and
388+
<li><p>Let <var>value</var> be the <a for=header>combined value</a> with <var>name</var> and
372389
<var>list</var>.
373390

374391
<li><p><a for=list>Append</a> <var>name</var>-<var>value</var> to <var>headers</var>.
@@ -389,8 +406,8 @@ token production.
389406
<p>A <a for=header>value</a> is a <a>byte sequence</a> that matches the following conditions:
390407

391408
<ul class=brief>
392-
<li><p>Has no leading or trailing <a>HTTP whitespace bytes</a>.
393-
<li><p>Contains no 0x00, 0x0A or 0x0D bytes.
409+
<li><p>Has no leading or trailing <a>HTTP tab or space bytes</a>.
410+
<li><p>Contains no 0x00 (NUL) or <a>HTTP newline bytes</a>.
394411
</ul>
395412

396413
<p class=note>The definition of <a for=header>value</a> is not defined in terms of an HTTP token
@@ -2495,7 +2512,31 @@ response <a for=/>header</a> can be used to require checking of a <a for=/>respo
24952512
`<code>Content-Type</code>` <a for=/>header</a> against the <a for=request>destination</a> of a
24962513
<a for=/>request</a>.
24972514

2498-
<p>Its <a for=header>value</a> <a>ABNF</a>:
2515+
<p>To <dfn>determine nosniff</dfn>, given a <a for=/>header list</a> <var>list</var>, run these
2516+
steps:
2517+
2518+
<ol>
2519+
<li><p>Let <var>value</var> be the result of <a for="header list">getting</a>
2520+
`<a http-header><code>X-Content-Type-Options</code></a>` from <var>list</var>.
2521+
2522+
<li><p>If <var>value</var> is null, then return false.
2523+
2524+
<li><p>Let <var>stringValue</var> be the <a>isomorphic decode</a> of <var>value</var>.
2525+
2526+
<li><p>Let <var>tokens</var> be the result of
2527+
<a lt="strictly split a string">strictly splitting</a> <var>stringValue</var> on U+002C (,).
2528+
2529+
<li><p>Let <var>firstToken</var> be the result of removing all <a>HTTP tab or space</a> from the
2530+
start and end of <var>tokens</var>[0].
2531+
2532+
<li><p>If <var>firstToken</var> is an <a>ASCII case-insensitive</a> match for
2533+
"<code>nosniff</code>", then return true.
2534+
2535+
<li><p>Return false.
2536+
</ol>
2537+
2538+
<p>Web developers and conformance checkers must use the following <a for=header>value</a>
2539+
<a>ABNF</a> for `<a http-header><code>X-Content-Type-Options</code></a>`:
24992540

25002541
<pre>
25012542
X-Content-Type-Options = "nosniff" ; case-insensitive</pre>
@@ -2507,16 +2548,8 @@ X-Content-Type-Options = "nosniff" ; case-insensitive</pre>
25072548
<p>Run these steps:
25082549

25092550
<ol>
2510-
<li><p>If <var>response</var>'s <a for=response>header list</a>
2511-
<a for="header list">does not contain</a> `<a http-header><code>X-Content-Type-Options</code></a>`,
2512-
then return <b>allowed</b>.
2513-
2514-
<li><p>Let <var>nosniff</var> be the result of <a>extracting header values</a> from the
2515-
<em>first</em> <a for=/>header</a> whose <a for=header>name</a> is a <a>byte-case-insensitive</a>
2516-
match for `<a http-header><code>X-Content-Type-Options</code></a>` in <var>response</var>'s
2517-
<a for=response>header list</a>.
2518-
2519-
<li><p>If <var>nosniff</var> is failure, then return <b>allowed</b>.
2551+
<li><p>If <a>determine nosniff</a> with <var>response</var>'s <a for=response>header list</a> is
2552+
false, then return <b>allowed</b>.
25202553

25212554
<li><p>Let <var>mimeType</var> be the result of <a for="header list">extracting a MIME type</a>
25222555
from <var>response</var>'s <a for=response>header list</a>.
@@ -2575,14 +2608,10 @@ run these steps:</p>
25752608
<var>mimeType</var> (ignoring parameters) is a <a>CORB-protected MIME type</a>, then return
25762609
<b>blocked</b>.
25772610

2578-
<li><p>Let <var>nosniff</var> be the result of <a>extracting header values</a> from the
2579-
<em>first</em> <a for=/>header</a> whose <a for=header>name</a> is a <a>byte-case-insensitive</a>
2580-
match for `<a http-header><code>X-Content-Type-Options</code></a>` in <var>response</var>'s
2581-
<a for=response>header list</a>.
2582-
25832611
<li>
2584-
<p>If <var>nosniff</var> is not failure and <var>mimeType</var> (ignoring parameters) is a
2585-
<a>CORB-protected MIME type</a> or <code>text/plain</code>, then return <b>blocked</b>.
2612+
<p>If <a>determine nosniff</a> with <var>response</var>'s <a for=response>header list</a> is true
2613+
and <var>mimeType</var> (ignoring parameters) is a <a>CORB-protected MIME type</a> or
2614+
<code>text/plain</code>, then return <b>blocked</b>.
25862615

25872616
<p class="note no-backref">CORB only protects <code>text/plain</code> responses with a
25882617
`<code>X-Content-Type-Options: nosniff</code>` header. Unfortunately, protecting such responses
@@ -4863,7 +4892,7 @@ invoked, must run these steps:
48634892
<li><p>If the <a>context object</a>'s <a for=Headers>header list</a>
48644893
<a for="header list">does not contain</a> <var>name</var>, then return null.
48654894

4866-
<li><p>Return the <a for=header>combined value</a> given <var>name</var> and the
4895+
<li><p>Return the <a for=header>combined value</a> with <var>name</var> and the
48674896
<a>context object</a>'s <a for=Headers>header list</a>.
48684897
</ol>
48694898

@@ -6602,6 +6631,7 @@ Anssi Kostiainen,
66026631
Arkadiusz Michalski,
66036632
Arne Johannessen,
66046633
Arthur Barstow,
6634+
Asanka Herath,
66056635
Axel Rauschmayer,
66066636
Ben Kelly,
66076637
Benjamin Gruenbaum,

0 commit comments

Comments
 (0)