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

Prevent cross-origin sensitive header probing #1434

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 85 additions & 6 deletions fetch.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,56 @@ format of range header value can be set using <a>add a range header</a>.
<a>implementation-defined</a> <a for=/>header value</a> for the `<code>User-Agent</code>`
<a for=/>header</a>.

<p>To
<dfn export for="header list" id=concept-header-list-filter-include>filter include</dfn> a
<a for=/>header list</a> <var>list</var> and <a for=/>header name</a>s <var>includeNames</var>, run these steps:
arichiv marked this conversation as resolved.
Show resolved Hide resolved

<ol>
<li>Let <var>filteredList</var> be an empty <a for=/>header list</a>.
arichiv marked this conversation as resolved.
Show resolved Hide resolved

<li><a for=list>For each</a> (<var>name</var>, <var>value</var>) in <var>list</var>:

<ol>
<li>If <var>name</var> in <var>includeNames</var> then <a for=list>append</a> (<var>name</var>, <var>value</var>) to <var>filteredList</var>.
arichiv marked this conversation as resolved.
Show resolved Hide resolved
</ol>

<li><p>Return <var>filteredList</var>.
</ol>

<p>To
<dfn export for="header list" id=concept-header-list-filter-exclude>filter exclude</dfn> a
<a for=/>header list</a> <var>list</var> and <a for=/>header name</a>s <var>excludeNames</var>, run these steps:

<ol>
<li>Let <var>filteredList</var> be an empty <a for=/>header list</a>.

<li><a for=list>For each</a> (<var>name</var>, <var>value</var>) in <var>list</var>:

<ol>
<li>If <var>name</var> not in <var>excludeNames</var> then <a for=list>append</a> (<var>name</var>, <var>value</var>) to <var>filteredList</var>.
</ol>

<li><p>Return <var>filteredList</var>.
</ol>

<p>To
<dfn export for="header list" id=concept-header-list-get-the-size>get the size</dfn> of a
<a for=/>header list</a> <var>list</var>, run these steps:

<ol>
<li>Let <var>sizeInBytes</var> be `0`.

<li><a for=list>For each</a> (<var>name</var>, <var>value</var>) in <var>list</var>:

<ol>
<li>Add the size of <var>name</var> to <var>sizeInBytes</var>.
arichiv marked this conversation as resolved.
Show resolved Hide resolved
<li>Add `2` to <var>sizeInBytes</var> (represents the `: ` after the name).
arichiv marked this conversation as resolved.
Show resolved Hide resolved
<li>Add the size of <var>value</var> to <var>sizeInBytes</var>.
<li>Add `2` to <var>sizeInBytes</var> (represents the `\r\n` after the value).
</ol>

<li><p>Return <var>sizeInBytes</var>.
</ol>

arichiv marked this conversation as resolved.
Show resolved Hide resolved
<h4 id=statuses>Statuses</h4>

Expand Down Expand Up @@ -2864,6 +2914,33 @@ run these steps:
<li><p>Return <b>allowed</b>.
</ol>

<h3 dfn export lt="is a cors requests header size over the limit" id=is-a-cors-requests-header-size-over-the-limit>
Is a CORS request's header size over the limit?</h3>
arichiv marked this conversation as resolved.
Show resolved Hide resolved

Note: The goal of this algorithm is to prevent cross-origin requests from probing the size of sensitive <a for=/>header</a>s
(`<a http-header><code>Authorization</code></a>` or `<a http-header><code>Cookie</code></a>`) by adding <a for=/>header</a>s
to cross-site requests until the total size of all HTTP request <a for=/>header</a>s exceeds the server side limit. If this
arichiv marked this conversation as resolved.
Show resolved Hide resolved
algorithm returns true, the <a>CORS-preflight request</a> must be run. In order for this approach to succeed, servers should
not set a HTTP request <a for=/>header</a>s size limit below 8KB.

<p>Run these steps to check if <dfn>the header size is over the CORS limits</dfn> on the provided <var>request</var>:

<ol>
<li><p>If <var>request</var>'s <a for=request>origin</a> is <a>same origin</a> with <var>request</var>'s
<a for=request>current URL</a>'s <a for=url>origin</a>, return `false`.

<li><p>Let <var>sensitiveHeaderList</var> be the result of running <a for="header list">filter include</a> on <var>request</var>'s
<a for=response>header list</a> with `(<a http-header><code>Authorization</code></a>, <a http-header><code>Cookie</code></a>) as <var>includeNames</var>`.

<li><p>If the result of running <a for="header list">get the size</a> on <var>sensitiveHeaderList</var> is greater than 4KB, return `true`.
arichiv marked this conversation as resolved.
Show resolved Hide resolved

<li><p>Let <var>nonSensitiveHeaderList</var> be the result of running <a for="header list">filter exclude</a> on <var>request</var>'s
<a for=response>header list</a> with `(<a http-header><code>Authorization</code></a>, <a http-header><code>Cookie</code></a>) as <var>excludeNames</var>`.

<li><p>If the result of running <a for="header list">get the size</a> on <var>nonSensitiveHeaderList</var> is greater than 4KB, return `true`.

<li><p>Return `false`.
</ol>


<h2 id=http-extensions>HTTP extensions</h2>
Expand Down Expand Up @@ -4628,17 +4705,19 @@ these steps:

<ol>
<li>
<p>If <var>makeCORSPreflight</var> is true and one of these conditions is true:
<p>If one of these conditions is true:

<ul class=brief>
<li><p>There is no <a>method cache entry match</a> for <var>request</var>'s
<a for=request>method</a> using <var>request</var>, and either <var>request</var>'s
<li><p><var>makeCORSPreflight</var> is true and there is no <a>method cache entry match</a> for
<var>request</var>'s <a for=request>method</a> using <var>request</var>, and either <var>request</var>'s
<a for=request>method</a> is not a <a>CORS-safelisted method</a> or <var>request</var>'s
<a>use-CORS-preflight flag</a> is set.

<li>There is at least one <a for=list>item</a> in the <a>CORS-unsafe request-header names</a>
with <var>request</var>'s <a for=request>header list</a> for which there is no
<a>header-name cache entry match</a> using <var>request</var>.
<li><var>makeCORSPreflight</var> is true and there is at least one <a for=list>item</a> in the
<a>CORS-unsafe request-header names</a> with <var>request</var>'s <a for=request>header list</a>
for which there is no <a>header-name cache entry match</a> using <var>request</var>.

<li><a>The header size is over the CORS limits</a> for <var>request</var>.
arichiv marked this conversation as resolved.
Show resolved Hide resolved
</ul>

<p>Then:
Expand Down