2

Basic Auth, including Bearer tokens, depend on using TLS to prevent eavesdroppers from getting at your sensitive credentials or tokens. But I think there is an Elephant in the room that nobody talks about.

Users often only type in "www.somesite.com" in stead of "https://www.somesite.com". AFAIK when you don't specify the protocol, the client browser will first try the default, un-encrypted HTTP connection.

The problem is that the user is basically asking for an un-encrypted connection to be made to the server because that's the default when no protocol is specified. The browser could potentially include sensitive information in the request headers, including Basic Auth credentials, Tokens, (and even Cookies that are not set "Secure")

For API clients that send tokens the situation is similar, but partially mitigated by hopefully well written client applications that

  1. Actually use only the SSL encrypted port to connect to, and
  2. The Developer actually turned the "Check the SSL certificate" option on before he published their app.

I'm of a mind to set up a MITM proxy on my home network to start checking and logging the apps that I use. In particular I want to spoof some DNS records and see whether the apps actually baulk at sending your credentials/tokens to the wrong server.

I personally would have preferred JWT to be specified as being sent in a SECURE cookie only, rather than in the headers... Does anybody here think my concern is not warranted?

EDIT: To clarify: I'm not so much worried by the weakness of SSL or attacks against DNS, I am more worried about credentials being exposed because clients end up sending it over unencrypted connections in any case, whether due to user's bad behaviour or because the client just follows redirects to SSL ports but only after sending the user's credentials. When designing APIs I will from now on add a listener on the unencrypted port. If it receives any token on that port, it will

  1. Not Redirect, and
  2. invalidate the credentials, and
  3. send the user a warning.

Hopefully developers who write apps that consume these APIs will get the hint. Would blacklisting the IP for a few hours be too harsh?

P.S. Note: With Secure cookies we still depend on the browser being correctly implemented.

Johan
  • 491
  • 5
  • 17

3 Answers3

3

the client browser will first try the default, un-encrypted HTTP connection, potentially including your Authorization header if the browser has got this details.

I think this assumption is wrong: The browser distinguishes between http:// and https://, i.e. credentials entered on https:// will not be included when accessing http:// and vice versa. This means the browser will only include the credentials for basic authentication on http:// if the user has entered the credentials before on http://. And the browser only asked for the credentials on http:// if the server issued a 401 (authentication required) on http://. If the server instead simply redirects to https:// and only issues the 401 there then the browser will never ask for the credentials on http:// and thus not store the credentials for http:// and not include the credentials on http://.

Steffen Ullrich
  • 190,458
  • 29
  • 381
  • 434
  • This is really good to know. It goes a long way to alleviating one of the three problems (Eg the user goes back to a site but omit the protocol). But do you have a reference for this claim? – Johan Oct 04 '16 at 15:22
  • @Johan How does the client know that it has to send credentials or token in a HTTP Header while making the first request? – JOW Oct 04 '16 at 15:35
  • @Johan: The RFC for basic authentication does not specify how caching should be done. But in HTTP authentication is done for a URL and not a domain and that's why the caching includes the protocol (might even include path). If you don't believe me just try it. – Steffen Ullrich Oct 04 '16 at 16:47
  • It is not about believing you. I'm sure it is implemented exactly as you say - by the "trusted" names in browsers. I want to know about a recommended standard that says it should be so, something I can refer to when talking to developers who will consume my API. – Johan Oct 06 '16 at 05:28
  • Also please explain why you mention caching in this context? – Johan Oct 06 '16 at 05:30
  • @JOW A general purpose client eg a browser could not know, and would probably not have the credentials on first connection. On the other hand in the case of a purpose build client that is made to consume one specific API, it probably have exactly this built in. For APIs that are not interpreted by humans I don't think the world is ready for HATEOAS. – Johan Oct 06 '16 at 05:34
  • @Johan If you are not refering to a regular browser then please edit the second Paragraph in your Question. Also, If the Client and Server are purpose built, then why is the Client accessing port 80 and why does the server even have port 80 open? – JOW Oct 06 '16 at 09:44
  • @JOW is that better? – Johan Oct 06 '16 at 10:07
  • 1
    @Johan: After your edit it looks for me like you are designing an API which (non-browser) clients should use. In this case simply make the API only available with HTTPS and not HTTP and you no longer have the problem that clients might inadvertently use HTTP with unprotected credentials. – Steffen Ullrich Oct 06 '16 at 11:37
  • @Johan OK. check out my answer. – JOW Oct 06 '16 at 15:06
1

Any token-based auth has a problem with MiTM attacks. The token standards do not include any mechanism to prevent them.

That means that every app needs to take this into account. You can reduce the risk by keeping token lifetimes very short or you can add a server-side mechanism to track whether the token is coming from the original client.

In this way, virtually all of the token auth examples you see are wrong. Or at least missing this crucial detail.

So yes, in general you are absolutely correct.

Julian Knight
  • 7,102
  • 18
  • 23
  • My issue is that even when you use SSL, people still potentially end up exposing their credentials, either because they don't type out the protocol part of the URL, or because of badly written clients that TRY http before https, or because developers forget to turn on the certificate check when they "go production". – Johan Oct 04 '16 at 13:30
  • Maybe I've not quite understood the Q. No credentials should ever be passed in the clear of course whether a uid/pw login or a token. Tokens should only ever be valid for the protocol they were created on so a token created on https shouldn't be accepted on http. But certainly tokens are vulnerable if intercepted because most examples don't show additional protections to prevent MiTM. I think we may be "agreeing violently" ;) – Julian Knight Oct 04 '16 at 14:04
0

First off, HTTP Basic Authentication and REST are both Stateless. Meaning - it is solely up to the Client to manage the session. Unless used for Server to Server communication, using HTTP Basic Authentication with REST is just a Bad Combo. I'd suggest changing your authentication method. refer the Authentication Section in the Accepted Answer here

For Addressing the Username/Password leak, my suggestion will be to:

JOW
  • 2,317
  • 2
  • 17
  • 24