Why HTTP Basic Auth is Bad

The most simple way to restrict access to a resource on a web server is to use a method called HTTP Basic Authentication. This dates back to the 1996 definition of HTTP/1.0 which became the first widely accepted authentication scheme. This approach was not as secure as other schemes that were developed later. The current prevailing mechanism is to use token based authentication. The token is either provided by the web server, or a dedicated authentication service.  The client either stores the token in a cookie value kept in the web browser, or sends it in specific HTTP request header for each web request. This is the prevailing method of authentication for cloud API services today. Another popular one is OAuth.

I don’t like HTTP Basic Auth for a number of different reasons, and have avoided it for many years. When asked by a colleague today why I don’t like it, I began thinking of all the reasons why. Here is the full list:

1) HTTP Basic is less secure than a token based system because the username and password credentials are carried by every single request between the client and the server. Username and password credentials do not typically expire, and if they do, it’s not very often. Using a token allows the token to be regularly expired (typically in a number of minutes), and the actual account credentials are only ever transmitted between the client and the authentication service to acquire the valid token to start with, and upon expiration.

2) HTTP Basic is typically protected by routing all content over SSL/TLS protocols. Although SSL/TLS is assumed to be secure, it is possible to defeat their security, and it’s better not to depend on it for every request.

3) The effective attack surface for a system that supports HTTP Basic is much bigger than one that uses tokens issued from a central auth service.

  • With HTTP Basic Auth, each web server needs to be able to validate usernames and passwords. This means that it must have a copy of the password hashes, or that it must have access to a remote system that can validate them. An attacker need only compromise any one of the service endpoints in order to intercept the credentials and potentially re-exploit a given account even after a significant period of time has elapsed.
  • The amount of server-side source code that could contain bugs that are vulnerable to security exploits will continue to grow over time as the system grows and new features are added, whereas if the auth service is standardized and centralized, it can be more easily protected, is less subject to change, and does not need to be scaled out to the same extent.

4) For performance reasons, security credentials may need to be cached on the servers that handle high volumes of requests. This raises another set of concerns about keeping the cached data secure, and adds complexity to operational tasks such as the revocation of access to an account. If account information is widely cached, it may be complicated to remove it everywhere.

5) Systems that use token based authentication could offer a service over HTTP that does not use SSL/TLS for high performance use cases where the overhead of encryption is not acceptable. Special encrypted read-only tokens could be issued for this purpose. Such tokens could be carried in web browsers using cookies. With HTTP Basic, special read-only accounts would be needed to produce the equivalent. Automated password expiration in that case would be awkward, and usually impractical.

6) For web use cases, there is no good way to allow a web user to “log out” of an HTTP Basic Auth session. Although there are some convoluted and stupid workarounds, the only reliable method is to ask users to quit their web browser in order to log out. Yuck!

If there is any doubt, please don’t use HTTP Basic Auth. I’m asking you nicely.

You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.

4 Comments »

 
  • Vid Luther says:

    What about for one-offs? I still find it easier for me to put a site behind basic auth for prototypes that only 2-3 people will see.

  • Adrian Otto says:

    My guidance pertains to serious systems where security is important. HTTP Basic Auth is easy to set up for one-offs, so you can still do that. Simply recognize that there are other, more secure options available for those use cases that warrant something stronger and more flexible.

  • Gilbert Pilz says:

    I agree with most of your article, but I do have a few nits to pick.

    Most of the problems you point out apply to any authentication mechanism that follows the ID/password pattern. Not that this makes Basic Auth any better, but I think we need to be clear that the root cause of the problem is password expiration/revocation and that this doesn’t have anything in particular to do with the way in which Basic Auth implements the ID/password pattern.

    Point 3, Bullet 1: A service that uses token-based auth similarly needs to validate the token that is presented to it. I don’t see any win for token-based auth on this point.

    Point 3, Bullet 2: This is really just a restatement of Point 1.

    Point 3, Bullet 3: I don’t see how this has anything in particular to do with Basic Auth. Any platform that supports Basic Auth will have implemented and tested the modules that do the LDAP lookup etc. for quite some time now. The problem of coding the authorization checks etc. are the same, no matter what authentication mechanism you use.

  • Adrian Otto says:

    Good debate material!!

    > Most of the problems you point out apply to any authentication mechanism that follows the
    > ID/password pattern. Not that this makes Basic Auth any better, but I think we need to be
    > clear that the root cause of the problem is password expiration/revocation and that this
    > doesn’t have anything in particular to do with the way in which Basic Auth implements the
    > ID/password pattern.

    Yes, exactly. I would oppose any authentication approach that sends usernames/passwords with every request between a client and server under the same criticism. The more times you send your account credentials over the wire, the greater the chance of security compromise, regardless if you protect that data with encryption or not.

    > Point 3, Bullet 1: A service that uses token-based auth similarly needs to validate the
    > token that is presented to it. I don’t see any win for token-based auth on this point.

    Tokens have relatively short expiry periods, where account credentials (username/password) have relatively long ones. This means that the compromise of a token has a more limited scope of risk. Tokens may also be offered with limited access control without the need for multiple username/password pairs. The more username/password pairs that exists for an account, the more risk is exposed.

    > Point 3, Bullet 2: This is really just a restatement of Point 1.

    True, I adjusted my post to consolidate both sentences on the same bullet, as the second sentence is simple expanding on the first.

    > Point 3, Bullet 3: I don’t see how this has anything in particular to do with Basic Auth.
    > Any platform that supports Basic Auth will have implemented and tested the modules that
    > do the LDAP lookup etc. for quite some time now. The problem of coding the authorization
    > checks etc. are the same, no matter what authentication mechanism you use.

    In the context of using a token scheme with a username/password scheme, token validation is lower risk than username/password validation. This is because tokens can come with restricted access control, and shorter expiry periods.

    To illustrate my point, check to see how your bank allows on-line banking. I will bet you $100 cash they do not use any scheme that sends your account username and password with every interaction between your browser and their web site. If I lose the bet, use my $100 to open an account with another bank!

 

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam protection by WP Captcha-Free