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

HTTPS upgrades proposal #1655

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all 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
137 changes: 135 additions & 2 deletions fetch.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2162,6 +2162,17 @@ Unless stated otherwise, it is false.

<p class=note>This flag is for exclusive use by HTML's render-blocking mechanism. [[!HTML]]

<p>A <a for=/>request</a> has an associated boolean <dfn export for=request>is HTTPS upgrade</dfn>.
Unless stated otherwise, it is false.

<p class=note>This is for exclusive use by HTTPS upgrading.

<p>A <a for=/>request</a> has an associated
<dfn export for=request>HTTPS upgrade fallback URL</dfn>, which is null or a <a for=/>URL</a>.
Unless otherwise stated, it is null.

<p class=note>This is for exclusive use by HTTPS upgrading.

<hr>

<p>A <a for=/>request</a> has an associated
Expand Down Expand Up @@ -3270,6 +3281,124 @@ through TLS using ALPN. The protocol cannot be spoofed through HTTP requests in
</div>


<h3 id=https-upgrading>HTTPS upgrading</h3>

<p>User agents may optionally upgrade requests with URLs that are not
<a>potentially trustworthy URLs</a> to attempt to fetch them over
<a>potentially trustworthy URLs</a>. If an upgraded request fails with a network error, it is
retried over the original URL.

<p>The HTTPS upgrading algorithm consists of <a>upgrade an HTTP request</a> and
<a>HTTPS upgrade fallback</a> algorithms.


<h4 id=https-upgrading-upgrade>HTTPS upgrade algorithm</h4>

<div algorithm>
<p>To <dfn>upgrade an HTTP request</dfn> given a <a for=/>request</a> <var>request</var>:

<ol>
<li>
<p>If any of the following are true:

<ul>
<li><p><var>request</var>'s <a for="request">destination</a> is not "<code>document</code>";

<li><p><var>request</var>'s <a for="request">method</a> is not "<code>GET</code>";

<li><p><var>request</var>'s <a for="request">URL</a>'s <a for="url">scheme</a> is not
"<code>http</code>"; or

<li><p><var>request</var>'s <a for="request">URL</a>'s <a for="url">origin</a> is exempted from
Copy link

Choose a reason for hiding this comment

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

So why isn't the HTTPS Upgrade opt-out mechanism defined in this spec or uselessly vauge? What if a site serves 2 different views or groups of assets, for clear vs TLS?

Copy link
Member

Choose a reason for hiding this comment

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

Generally that's considered a bug in the website at this point.

Copy link

Choose a reason for hiding this comment

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

In https://groups.google.com/a/chromium.org/g/blink-dev/c/cAS525en8XE/m/jAAG2CIPBgAJ a user reported a Polish LTE ISP, offers the UA subscriber's ISP specific GUID (lets ignore privacy) through a clear HTTP 1.1 ISP addon req header (MITM clear proxy), so a site has to downgrade to clear, capture the customer's ISP subscriber GUID, then redirect back to HTTPS, then on backend, submit LTE subscriber GUID+server's 3rd party api key->bill UA's LTE account for 3rd party service. No app stores, no native apps, no browser specific local or cloud storage of UA auto-logins, and no asking a UA to type in his telephone number. How would this continue to work if a clear HTTP is prohibited by spec globally? Someone demonstrated a business need to capture req headers from a clear MITM proxy.

Copy link
Member

Choose a reason for hiding this comment

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

ISPs broadcasting user identifiers in plain text is exactly why universal HTTPS matters.

upgrades in an <a>implementation-defined</a> way,
</ul>

<p>then return.
</li>

<li>
<p>If <var>request</var>'s <a for=request>HTTPS upgrade fallback URL</a> is non-null, then set
<a for=request>is HTTPS upgrade</a> to false and <a for=request>HTTPS upgrade fallback URL</a> to
null and return.

<p class=note>This is a fallback request that cannot be upgraded again.

<li>
<p>Otherwise:

<ol>
<li><p>Set <a for=request>HTTPS upgrade fallback URL</a> to <var>request</var>'s
<a for="request">URL</a>.

<li><p>Set <var>request</var>'s <a for="request">URL</a>'s <a for="url">scheme</a> to
"<code>https</code>".

<li><p>Set <a for=request>is HTTPS upgrade</a> to true.
</ol>
</li>
</ol>
</div>


<h4 id=https-upgrading-fallback>Fallback algorithm</h4>

<div algorithm>
<p>To run <dfn>HTTPS upgrade fallback</dfn> given a <a for=/>request</a> <var>request</var> and
<a for=/>response</a> <var>response</var>:

<ol>
<li><p>If <var>request</var>'s <a for=request>is HTTPS upgrade</a> is false, then return
<var>response</var>.

<li>
<p>If <var>response</var> is a <a>network error</a>:

<p class=note>This means that the upgrade failed and initiates a fallback load.

<ol>
<li><p>Let <var>serializedFallbackURL</var> be the <var>request</var>'s
<a for=request>HTTPS upgrade fallback URL</a>, <a lt="URL serializer">serialized</a> and
<a>isomorphic encoded</a>.

<li><p>Let <var>fallbackResponse</var> be a new <a for=/>response</a> whose
<a for=response>header list</a> is «
(`<code>Location</code>`, <var>serializedFallbackURL</var>) » and
<a for="response">status</a> is 307.

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

<li>
<p>Return <var>response</var>.

<p class=note>This means the upgrade was successful.
</ol>

<p class=note>User agents can implement a fast-fallback path by canceling slow fetches on upgraded
requests, in order to quickly initiate a fallback HTTP fetch.
</div>


<h4 id=http-upgrades-examples>Examples</h4>

<p id=example-https-upgrade-good-https class=example><code>a.com</code> serves both
<code>http://a.com</code> and <code>https://a.com</code>. An eligible request to
<code>http://a.com</code> will be upgraded to <code>https://a.com</code>.

<p id=example-https-upgrade-bad-https class=example><code>a.com</code> serves
<code>http://a.com</code> but refuses connections on <code>https://a.com</code>. An eligible
request to <code>http://a.com</code> will be upgraded to <code>https://a.com</code>, but the fetch
will fail. A fallback request will be initiated to <code>http://a.com</code>.

<p id=example-https-upgrade-allowlist class=example><code>site.test</code> serves
<code>http://site.test</code> but refuses connections on <code>https://site.test</code>. Upon
first request and fallback to <code>http://site.test</code>, the user agent stores the hostname
in an allowlist with an expiration time of 7 days. In a future request, if <code>site.test</code>
is still in this allowlist, the user agent will not upgrade <code>http://site.test</code> to
<code>https://site.test</code>. The user agent will also set the new expiration time of the
allowlist entry for <code>site.test</code> to 7 days from now.
annevk marked this conversation as resolved.
Show resolved Hide resolved



<h2 id=http-extensions>HTTP extensions</h2>

Expand Down Expand Up @@ -4457,6 +4586,8 @@ steps:

<li><p><a>Upgrade <var>request</var> to a potentially trustworthy URL, if appropriate</a>.

<li><p>Optionally, run <a>upgrade an HTTP request</a> algorithm on <var>request</var>.

<li><p><a>Upgrade a mixed content <var>request</var> to a potentially trustworthy URL, if appropriate</a>.

<li><p>If <a lt="block bad port">should <var>request</var> be blocked due to a bad port</a>,
Expand Down Expand Up @@ -6001,7 +6132,8 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:
<a for="fetch params">canceled</a>:

<ol>
<li><p>If <var>connection</var> is failure, then return a <a>network error</a>.
<li><p>If <var>connection</var> is failure, then return the result of running
<a>HTTPS upgrade fallback</a> given <var>request</var> and a <a>network error</a>.

<li><p>Set <var>timingInfo</var>'s <a for="fetch timing info">final connection timing info</a> to
the result of calling <a>clamp and coarsen connection timing info</a> with
Expand Down Expand Up @@ -8727,7 +8859,7 @@ resource — for non-<a>CORS requests</a> as well as <a>CORS
requests</a> — and do not use `<code>Vary</code>`.


<h3 class=no-num id=websocket-protocol oldids=websocket-connections,websocket-opening-handshake,fail-the-websocket-connection,the-websocket-connection-is-established>WebSockets</h2>
<h3 class=no-num id=websocket-protocol oldids=websocket-connections,websocket-opening-handshake,fail-the-websocket-connection,the-websocket-connection-is-established>WebSockets</h3>

<p>As part of establishing a connection, the {{WebSocket}} object initiates a special kind of
<a for=/>fetch</a> (using a <a for=/>request</a> whose <a for=request>mode</a> is
Expand Down Expand Up @@ -8991,6 +9123,7 @@ done only by navigations). The <a>fetch controller</a> is also used to
<a for=request>redirect mode</a> set to "<code>manual</code>".



<h2 id=acknowledgments class=no-num>Acknowledgments</h2>

<p>Thanks to
Expand Down
Loading