Is HTTP 426 acceptable for “Your request should have been HTTPS”

httphttps

I have an HTTP serving an API which works either anonymously or with a secret key in a header, like so:

GET /profile?authenticationKey
Authorization: 1234567890

I want to reject any request coming in over HTTP that uses an Authorization header, since those headers would come across in plain text. But I'm not sure what the appropriate response is.

I've considered 400 Bad Request with a note explaining why what they did was stupid and suggesting that they immediately invalidate their key.

But I'm wondering whether 426 Upgrade Required might be better or worse. It's a code specific to the idea that an HTTP request needs to be an HTTPS request, but reading RFC 2817 makes me think that it is designed to help switch to HTTPS from the same port. Can I use it in this case as well? If so, do I need to include an Upgrade: TLS/1.0 header as well?

Best Answer

The situation you are trying to avoid here is that of API users sending their credentials over the wire in a form easily sniffed by third parties.

If you either redirect to HTTPS or serve any HTTP error, you don't avoid this situation; the credentials are already sent before you have a chance to respond.

The only really proper thing to do is to not serve the API on HTTP at all, not even for anonymous requests. For your API server, ideally there should not be a server listening on port 80 at all. If you must have that IP address listening on port 80 (e.g. because you don't have any spare IP addresses), then you should return 403 Forbidden or 404 Not Found for API requests. Optionally you could capture and invalidate such credentials as were sent mistakenly over HTTP, but it's best to simply not listen on HTTP at all.

Related Topic