Secure your redirects!
Published 2015-6-9NPM Module
See https://www.npmjs.com/package/redirect-https
TL;DR
Brick insecure cURL and API requests while still providing an optimal experience for browser users:
<html>
<head>
<meta http-equiv="refresh" content="0;URL='https://example.com/foo'"/>
</head>
<body>
<!--
Hello Mr. Web Developer!
This page is only available to users with private and secure connections.
Please do not include insecure urls in your examples.
Instead, please use https://example.com/foo
-->
</body>
</html>
Since a Location 301 redirect takes the same amount of time (latency) as a meta refresh, you can provide additional security by ensuring that when developers and such don't accidentally create insecure "working" examples, and yet the average user will experience the redirect just as if it had been a Location 301.
Be sure to use HSTS headers and submit your site in the HSTS Browser Preload List for even lower latency: https://hstspreload.appspot.com/
DANGER: Be sure to HTML Escape the URL before inserting it into a meta tag - otherwise an attacker can create a link that inserts a script tag into your page and could potentially initiate an API call with the cookies of your user.
:-D
HTTP is dead, long live HTTPS
We are entering the world of HTTP/2.0, where proper TLS encryption isn't even an option.
Granted, we're probably going to say SSL when we actually mean TLS for the next hundred years - just like we still call JSON Web Requests "AJAX" and refer to DOM as JavaScript (which is actually ECMAScript) - but regardless of what we call it, it's the way of the future (and the now - Yay for LetsEncrypt).
HTTP MUST DIE
You're reading my blog. You're probably a web developer. You probably work with other web developers.
What's worse: A) having code that sometimes works, or B) code that always breaks?
The correct answer is B). If your code is broken, you will fix it. If your code is only sometimes broken, you might not know until something really bad happens.
We need to break http so that people don't use it accidentally. If we break it, we'll discourage it's use and encourage more people to fix their insecure code.
HTTP MUST LIVE
Obviously we have to support HTTP - not all browsers support HSTS yet.
One day you'll type example.com into your browser and it will try https://example.com by default and then fall back to http://example.com if the secure attempt failed.
One day, hopefully, we'll see a security warning for any site that hasn't upgraded to a secure protocol.
But today is not that day.... :-/
Have AND Eat your Cake
But, as it turns out, we can kinda get both in this case. :-D
The conventional approach to upgrading people to HTTPS is to issue a 301 Redirect in the HTTP headers that looks like this:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/foo
The problem with that is that cURL and many API libraries will still work - they'll simply resend the request and you're average developer will be none-the-wiser.
For both Search Engines (SEO) and Browsers a meta redirect has all of the advantages of a Location redirect, but none of the disadvantages.
<meta http-equiv="refresh" content="0;URL='https://example.com/foo'"/>
- The Search Engine still knows to index the page you're redirecting to.
- The browser still only has 1 extra round-trip
- The browser still redirects instantly
- cURL will return an unexpected result that will catch the developers eye
- An API call from their programming language will fail to produce consumable data
It's a win-win-win-win-win - all the way around!!!
DANGER: SCRIPT INJECTION!!!
Can you see the HUGE vulnerability here?
<meta http-equiv="refresh" content="0;URL='{{ VULNERABLE_URL }}'"/>
What if I posted a link to http://yourbank.com/<script>alert('pwnd!')</script>
with the text
Cutest Ever Cat PICS! OMG!!!
in a comment to your blog post on cute animals?
Can you see it now?
If you use this technique, you MUST HTML ESCAPE the dynamic URL.
<meta http-equiv="refresh" content="0;URL='{{ ESCAPED_URL }}'"/>
Sidenote:
Can you imagine how much safer (not to mention easy to develop) the web would be
if HTML5 was an opt-in that required well-formed, parsable HTML?
I mean, if the only way you could use the audio
and video
tags - or the File APIs -
was if your HTML was actually valid, it wouldn't even be possible to exploit a meta
tag this way on most popular sites.
Too bad we always seem to err on the side of stupid...
But what about HTTPS Upgrade!?
There is such a thing as HTTPS upgrade, but I couldn't find a clear explanation or example with a quick Google search.
And even the good folks over at StackOverflow don't know how well-supported it is.
That's a no for me.
PS
I'm completely baffled at how some websites have recently switched FROM using https TO NOT using. Amazon just switched a week or so ago and it blows my mind! I'd like to be able to privately browse their store... oh well.
It makes no sense and makes me very sad. Shame on you Amazon. Srsly...
By AJ ONeal
Did I make your day?
Buy me a coffee
(you can learn about the bigger picture I'm working towards on my patreon page )