Security through obscurity with HTTP Basic Authentication
October 17, 2010,
One of the undying fallacies of web development is that an application can be secured by requiring that the users authenticate themselves using HTTP Basic Authentication. We regularly have to explain to developers how easy it is to extract the authentication data from a request. So it's probably useful to put this down in writing for future reference.
Occasionally we're asked to install web applications that use HTTP Basic Authentication as a 'security measure', or to review code that claims the same. The notion is that since a user must provide a username and a password, access to an application and its data is sufficiently restricted, and no additional measures are required. Now if the mechanism used in HTTP Basic Authentication were robust, there would be a basis for this assumption, provided that the application itself handles the authorization. The problem is that the authentication mechanism is not robust, and relying on HTTP Basic Authentication alone will not secure your application. A short explanation of how the authentication mechanism works will clarify why.
I'm not going to explain how to set up HTTP Basic Authentication, there are numerous examples for it. But assuming you have configured a directory or a virtual host with authentication, the first request you make will not be answered with a 200 response code, but with a 401 (Authentication Required) response code. The browser responds to this by displaying the familiar prompt for a username and a password in a dialog. When the authentication parameters are entered, the browser sends these to the server as part of the headers of a new request. When the submitted authentication data are valid, the server will send the initially requested page.
The weakness of HTTP Basic Authentication lies in the way the username and password are sent to the server. This is done by adding a header named 'Authorization' to the request headers:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
The content of this header looks like it is encrypted, but in reality it is a base64 encoded string. If you decode the string above, you will get 'username:password'. And, since HTTP is a stateless protocol, your browser conveniently adds this header to any consecutive request, so you don't have to reauthenticate at each request. Any system that intercepts the request headers can easily extract the authentication data.
Just remember, HTTP Basic Authentication sends authentication data in encoded (not encrypted) form with each request. It offers no security. What you should conclude from that is that in principle you should only use HTTP Basic Authentication in situations where connections are encrypted using SSL. Also, you should not use account data for applications that use HTTP Basic Authentication, that you also use in other environments.