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

UPGRADE: Consider upgrade-insecure-requests in an insecure response as redirecting. #212

Closed
mikewest opened this issue Mar 9, 2015 · 6 comments
Labels

Comments

@mikewest
Copy link
Member

mikewest commented Mar 9, 2015

If a user navigates to http://example.com/ (insecure), and receives Content-Security-Policy: upgrade-insecure-requests as a response header, her client should behave as though it received a redirect response to https://example.com/.

This would remove the necessity for sending a positive Prefer: return=secure-representation signal on insecure navigations, as the server can simply opt-in on insecure responses.

Without thinking about it too hard, this seems clever. :)

@yoavweiss
Copy link
Contributor

One issue that I see here is that you're punishing upgrade-capable UAs the first time they access the site over HTTP, by forcing them to download the full response (or a large chunk of it, assuming they RST it), and then re-download it over HTTPS. At the end of this redirect the server can serve HSTS headers, making this problem go away for this particular user. Alternatively, we can also pin the Upgrade-capable server, and skip the redirect dance in followup sessions.

The secondary issue is that legacy UAs over HTTPS cannot be redirected away back to the unsafe, but intact, HTTP version. A JS API that exposes if the UA is Upgrade-capable can resolve that issue using a client-side redirect.

So, all in all, both are a very reasonable price to pay for not spamming the Web forever and ever.:+1:

@mikewest
Copy link
Member Author

Copy/pasting from the thread with @igrigorik:


If we have that in place, perhaps we could reverse the signaling by adding an upgraded: 1 header for requests that were rewritten on the client-side from HTTP to HTTPS. That is:

  1. User requests http://example.com/
  2. Server response includes the upgrade directive.
  3. User agent interprets that directive as a redirect to https://example.com/
  4. User agent requests https://example.com/, and includes an upgraded: 1 request header.
  5. Server sees that header, says "Hooray!", and locks the user into HTTPS via HSTS.

This clearly addresses the "modern client" use case, and could be abused to address the "legacy vs modern" use case for those sites that really care if we're willing to suffer another redirect:

  1. User requests https://example.com/ (without an upgraded: 1 header).
  2. Server redirects to http://example.com/.
  3. If the user's client supports upgrades, goto Added frame-ancestors directive. #1 above.
  4. Otherwise, stay on sad, old HTTP.

I expect Ilya's head to explode while reading this ("Two redirects?! Are you MAD!?"). It solves the problem, but isn't pretty, and isn't something I'd hope that most sites care about. :)

@pde
Copy link
Contributor

pde commented Mar 16, 2015

Question: would the client remember the "upgraded" state? For how long and for what scope?

@mikewest
Copy link
Member Author

I could imagine clients experimenting with something like that, but I don't think it's behavior we should mandate (as it starts sliding into HSTS, and I think it would be a mistake to tightly couple upgrading and HSTS-like behaviors).

@pde
Copy link
Contributor

pde commented Mar 16, 2015

My expectation is that we will automatically deploy the "legacy vs modern" algorithm as the out-of-the-box default behaviour for the webservers that run the Let's Encrypt agent, since there won't be an easy way for us to tell if those sites suffer from mixed content or not, and we'll want to minimise breakage on old clients.

I don't have a completely clear picture yet of what you are proposing for that case. Let's keep things simple and assume it's a site that isn't ready for the strictures of HSTS, yet. Is the following accurate?

  1. When the server sees a typical incoming navigational HTTPS request, there is no upgraded: 1 header sent by the client, so
  2. The server sends a 307 redirect to HTTP, but with an upgrade: 1 directive.
  3. The client sees the upgrade: 1 header, ignores the 307, and re-requests the page with the upgraded: 1 header.
  4. This time, the server is happy and issues a 200 response with content.

Have I understood that correctly?

@mikewest
Copy link
Member Author

Closing. We're not doing this, but sending an HTTPS header instead.

mikewest pushed a commit to mikewest/webappsec that referenced this issue Jun 29, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants