HTTP Authentication Mechanisms

When the Web server receive an HTTP request message, it may respond to the client with an authentication challenge instead of directly serving the request. When the user is challenged they should repeat the request providing their secret credentials this time. If they do not match the server can challenge the client again or generate an error. If the credentials match, the request completes normally. This is called HTTP Challenge/Response Authentication Framework. It is an extensible framework for different authentication protocols using a set of control headers, which can vary for different protocols. HTTP officially provides two authentication protocols: basic authentication and digest authentication.

The basic authentication is considered insecure and the next several paragraphs will describes how it works and why it is insecure. The challenge request and response server follows with sample HTTP messages:

  1. The user sends an HTTP request to the server (the simplest one is a GET request for a particular resource):
    OPTIONS http://localhost/basicdav/ HTTP/1.1
    Host: localhost
    User-Agent: cadaver/0.22.3 neon/0.25.5
    Connection: TE
    TE: trailers
    
  2. If the resource is in a protected realm, the server returns a 401 Authorization Required response with a WWW-Authenticate header, which contains the type of the authentication protocol and the name of the realm:
    HTTP/1.1 401 Authorization Required
    Date: Thu, 25 May 2006 04:04:24 GMT
    Server: Apache/2.2.2 (FreeBSD) mod_ssl/2.2.2 \
      OpenSSL/0.9.7e-p1 DAV/2 SVN/1.3.1 mod_jk/1.2.15
    WWW-Authenticate: Basic realm="WebDAV Repository"
    Content-Length: 401
    Content-Type: text/html; charset=iso-8859-1
    
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
    ...
    </html>
    
  3. The user then provides their username and password for the realm. The user agent (the browser for example), joins them with a colon and encodes them to base64 format and sends the same request with the Authorization header containing the encoded username and password:
    OPTIONS http://localhost/basicdav/ HTTP/1.1
    Host: localhost
    User-Agent: cadaver/0.22.3 neon/0.25.5
    Connection: TE
    TE: trailers
    Authorization: Basic YWRtaW46YWRtaW4=
    
  4. The server decodes the username and the password, verifies that they match and returns the requested document with a 200 OK message:
    HTTP/1.1 200 OK
    Date: Thu, 25 May 2006 04:06:30 GMT
    Server: Apache/2.2.2 (FreeBSD) mod_ssl/2.2.2 \
      OpenSSL/0.9.7e-p1 DAV/2 SVN/1.3.1 mod_jk/1.2.15
    DAV: 1,2
    DAV: <http://apache.org/dav/propset/fs/1>
    MS-Author-Via: DAV
    Allow: OPTIONS,GET,HEAD,POST,DELETE,TRACE,PROPFIND, \
      PROPPATCH,COPY,MOVE,LOCK,UNLOCK
    Content-Length: 0
    Content-Type: httpd/unix-directory
    

The greatest security flow of the basic authentication is that it sends the password almost in plain text. If a malicious person sniffs for the above HTTP messages and gains especially the one with Authorization header, they can easily decode the password with the following command:

$ echo 'YWRtaW46YWRtaW4=' | base64 -d
admin:admin
The intruder may not even take the effort of reversing the password - they may simply construct a new HTTP message with the same Authorization header as in the sniffed message. This is called a replay attack.

Being so week the basic authentication is recommended for friendly environments, where the privacy is desired but not absolutely necessary or is recommend in combination of https.

The digest authentication was designed to fix the flaws of the basic authentication, namely it never sends the passwords across the network in an easily reversible format and prevents replaying attacks, even if the messages with the authentication information are captured. It uses one-way digest functions to convert the user credentials and transfer their digests. Even if the message is stolen, it will be extremely hard to find the credentials only from the digest. However, replay attacks are still possible. This is why the server pass to the client a nonce token which changes very often. The client then can append the nonce to the password before calculating the digest. Here is a high level and simplified description of the digest authentication handshake:

  1. When the server receives a request for a protected resource, it computes a nonce value. Then it sends to the client the standard 401 Authorization Required message, whose WWW-Authenticate header contains the realm, the nonce and the digest algorithms supported by the server:
    HTTP/1.1 401 Authorization Required
    Date: Sat, 27 May 2006 19:28:55 GMT
    Server: Apache/2.2.2 (FreeBSD) mod_ssl/2.2.2
      OpenSSL/0.9.7e-p1 DAV/2 SVN/1.3.1 mod_jk/1.2.15
    WWW-Authenticate: Digest realm="WebDAV Repository",
      nonce="IUqcGMoUBAA=192598696feca657ad41cd38e68bc8c0326b3c6d",
      algorithm=MD5, domain="/digestdav", qop="auth"
    Content-Length: 401
    Content-Type: text/html; charset=iso-8859-1
    
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
    ....
    </html>
    
  2. The client selects an algorithm and computes the digest mixing secret data as the password, public data as the realm and the time-limited nonce value. It then repeats its original request with the digest in the Authorization header:
    PROPFIND http://localhost/digestdav/ HTTP/1.1
    Host: localhost
    User-Agent: cadaver/0.22.3 neon/0.25.5
    Connection: TE
    TE: trailers
    Depth: 0
    Content-Length: 297
    Content-Type: application/xml
    Authorization: Digest username="admin",
      realm="WebDAV Repository",
      nonce="IUqcGMoUBAA=192598696feca657ad41cd38e68bc8c0326b3c6d",
      uri="http://localhost/digestdav/",
      response="0ec88e91b7c9daab200939d52965bb94",
      algorithm="MD5", cnonce="3744a1e7696f58c3b84e7f39ff75a7a9",
      nc=00000001, qop="auth"
    
    <?xml version="1.0" encoding="utf-8"?>
    <propfind xmlns="DAV:">
    ...
    </propfind>
    
  3. The server receives the digest, the chosen algorithm and the other data and computes the same digest. If it match with the client's digest, the validation is successful and the server fulfills the request:
    HTTP/1.1 207 Multi-Status
    Date: Sat, 27 May 2006 19:29:02 GMT
    Server: Apache/2.2.2 (FreeBSD) mod_ssl/2.2.2 \
      OpenSSL/0.9.7e-p1 DAV/2 SVN/1.3.1 mod_jk/1.2.15 \
    Authentication-Info: rspauth="8ffe579dc0d7fd8c20c2f2522aa74e29",
      cnonce="3744a1e7696f58c3b84e7f39ff75a7a9",
      nc=00000001, qop=auth
    Content-Length: 689
    Content-Type: text/xml; charset="utf-8"
    
    <?xml version="1.0" encoding="utf-8"?>
    <D:multistatus xmlns:D="DAV:"
      xmlns:ns1="http://apache.org/dav/props/"
      xmlns:ns0="DAV:">
    ...
    </D:multistatus>
    
    The server can possible precompute the next nonce and send in Authentication-Info in advance, so the client can issue the right digest the next time.

Иван Иванов 2006-06-23