-
Notifications
You must be signed in to change notification settings - Fork 343
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
CORB: blocking of nosniff and 206 responses #686
Changes from 14 commits
a422fe4
cb50fe9
2159547
7ac369c
48de6d8
7213189
5a7980c
efd0bd6
c4a5a28
f2c604b
cf4e5a3
d010a99
3011eef
188b36e
5884f85
862b86d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2354,6 +2354,60 @@ X-Content-Type-Options = "nosniff" ; case-insensitive</pre> | |
pertain to them. Also, considering "<code>image</code>" was not compatible with deployed content. | ||
|
||
|
||
<h3 id=corb>CORB</h3> | ||
|
||
<p class="note">Cross-origin read blocking, better known as CORB, is an algorithm which identifies | ||
dubious cross-origin resource fetches (e.g., fetches that would fail anyway like attempts to render | ||
JSON inside an <code>img</code> tag) and blocks them before they reach a web page. CORB reduces the risk of | ||
leaking sensitive data by keeping it further from cross-origin web pages. | ||
|
||
<p>A <dfn>CORB-protected MIME type</dfn> is an <a>HTML MIME type</a>, a <a>JSON MIME type</a>, or an | ||
<a>XML MIME type</a> excluding <code>image/svg+xml</code>. | ||
|
||
<p class="note no-backref">Even without CORB, accessing the content of cross-origin resources with | ||
<a>CORB-protected MIME types</a> is either managed by the <a>CORS protocol</a> (e.g., in case of | ||
{{XMLHttpRequest}}), not observable (e.g., in case of pings or CSP reports which ignore the | ||
response), or would result in an error (e.g., when failing to decode an HTML document embedded in an | ||
<code>img</code> tag as an image). This means that CORB can block <a>CORB-protected MIME types</a> | ||
resources without being disruptive to web pages. | ||
|
||
<p>To perform a <dfn noexport>CORB check</dfn>, given a <var>request</var> and <var>response</var>, | ||
run these steps:</p> | ||
|
||
<ol> | ||
<li><p>If <var>request</var>'s <a for=request>initiator</a> is "<code>download</code>", then return | ||
<b>allowed</b>. | ||
<!-- XXX If we recast downloading as navigation this step can be removed. --> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @annevk what's your feeling on making this page-visible? I've been frustrated in the past digging into a spec detail only to find there was useful information in an html comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That seems fine. |
||
|
||
<li><p>If <var>request</var>'s <a for=request>current url</a>'s <a for=url>scheme</a> is not an | ||
<a>HTTP(S) scheme</a>, then return <b>allowed</b>. | ||
|
||
<li><p>Let <var>mimeType</var> be the result of <a for="header list">extracting a MIME type</a> | ||
from <var>response</var>'s <a for=response>header list</a>. | ||
|
||
<li><p>If <var>response</var>'s <a for=response>status</a> is <code>206</code> and | ||
<var>mimeType</var> (ignoring parameters) is a <a>CORB-protected MIME type</a>, then return | ||
<b>blocked</b>. | ||
|
||
<li><p>Let <var>nosniff</var> be the result of <a>extracting header values</a> from the | ||
<em>first</em> <a for=/>header</a> whose <a for=header>name</a> is a <a>byte-case-insensitive</a> | ||
match for `<a http-header><code>X-Content-Type-Options</code></a>` in <var>response</var>'s | ||
<a for=response>header list</a>. | ||
|
||
<li><p>If <var>nosniff</var> is not failure and <var>mimeType</var> (ignoring parameters) is a | ||
<a>CORB-protected MIME type</a> or <code>text/plain</code>, then return <b>blocked</b>. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should have a note or something explaining why we block There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. @csreis might have an opinion on what is the right thing to do here - one one hand we want to protect as many sensitive resources as possible, OTOH dropping text/plain protections would avoid extra special-cases in the spec and in the code. |
||
|
||
<p class="note no-backref">CORB protects <code>text/plain</code> responses in presence of | ||
<var>nosniff</var> header, but not if <a for=response>status</a> is <code>206</code> to avoid | ||
breaking existing websites that serve video resources with <code>text/plain</code> MIME type. | ||
|
||
<!-- TODO: MIME type confirmation sniffing --> | ||
<!-- TODO: JSON security prefix sniffing --> | ||
|
||
<li><p>Return <b>allowed</b>. | ||
</ol> | ||
|
||
|
||
|
||
<h2 id=fetching>Fetching</h2> | ||
|
||
|
@@ -2689,9 +2743,22 @@ with a <i>CORS flag</i> and <i>recursive flag</i>, run these steps: | |
<a for=request>response tainting</a> to | ||
"<code>opaque</code>". | ||
|
||
<li><p>Return the result of performing a <a>scheme fetch</a> | ||
using <var>request</var>. | ||
<li><p>Let <var>noCorsResponse</var> be the result of performing a <a>scheme fetch</a> using | ||
<var>request</var>. | ||
<!-- file URLs end up here as they are not same-origin typically. --> | ||
|
||
<li><p>If the <a>CORB check</a> with <var>request</var> and <var>noCorsResponse</var> returns | ||
<b>allowed</b>, then return <var>noCorsResponse</var>. | ||
|
||
<li><p>Set <var>corbSanitizedResponse</var> to a new <a for=/>response</a> whose | ||
<a for=response>status</a> is <var>noCorsResponse</var>'s <a for=response>status</a>, | ||
<a for=response>HTTPS state</a> is <var>noCorsResponse</var>'s <a for=response>HTTPS state</a>, | ||
and <a for=response>CSP list</a> is <var>noCorsResponse</var>'s <a for=response>CSP list</a>. | ||
|
||
<p class="warning">The step above is an effective defense against side channel attacks, | ||
only if <var>noCorsResponse</var> doesn't reach the process that initiated the request. | ||
|
||
<li><p>Return <var>corbSanitizedResponse</var>. | ||
</ol> | ||
|
||
<dt><var>request</var>'s <a for=request>current url</a>'s | ||
|
@@ -6287,6 +6354,7 @@ Larry Masinter, | |
Liam Brummitt, | ||
Louis Ryan, | ||
Lucas Gonze, | ||
Łukasz Anforowicz, | ||
呂康豪 (Kang-Hao Lu), | ||
Maciej Stachowiak, | ||
Malisa<!-- malisas; GitHub -->, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wasn't clear to me that this note was talking about what happens aside from CORB.
Maybe start "Even without CORB…"?
Maybe "Accessing the content of cross-origin resources"? Since we allow cross origin resources for imgs, script CSS.
fetch()
can fetchno-cors
so it might not be a good example here.It isn't clear that this is presenting a list of things, so maybe: "…is managed either by the CORS protocol…".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Done.
Good point - I've removed the fetch() example and only left XHR (which AFAIK doesn't have an equivalent of no-cors mode).
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, XHR can't fetch no-cors.