Apache mod_auth_form & mod_session_crypto.

For a long time website owners have been able to leverage Apache’s basic authentication method to create a secure, private area on their website, but it was front-ended by the ugly authentication popup.  In Apache 2.4.x we can now use the handy mod_auth_form to implement that login within the webpage itself, with all the self styling goodness that you would want.

I’ve spent some time recently working on a project using form auth and I thought I’d share some of the knowledge I’ve gained while working on that.  The first thing that comes to mind is the fact that mod_auth_form requires the use of a session, which in turn requires the use of cookies.  This presents a security issue that needs to be considered when using mod_auth_form to protect an area of your website.

Let us first get a protected site up and running using mod_auth_form.

Step 1: Make sure that the proper modules are enabled / uncommented in your httpd.conf.

LoadModule auth_form_module modules/mod_auth_form.so
LoadModule request_module modules/mod_request.so
LoadModule session_module modules/mod_session.so
LoadModule session_cookie_module modules/mod_session_cookie.so

You will need those in order to use mod_auth_form as well as sessions and cookies. Note the location, depending on your installation you may need to edit the path of the modules.

Step 2: Create a directory that you would like to make private on your server like  /path/to/website/private.  What we’ll do is force any attempts to browse to something on yoursite.dom/private/ be required to login.

Step 3:  Create a protected directory in your httpd.conf for your website. If you are using VirtualHosts this entry would go into a VirtualHost directive.

<Directory "/path/to/website/private">
    AuthFormProvider file
    AuthType form
    AuthName "Reserved Area"
    Session On
    SessionCookieName session path=/
    require valid-user

    # This is the login page
    ErrorDocument 401 /login.html

    # This is the file containing users login data
    AuthUserFile /var/www/auth/.htpasswd
</Directory>

Step 4: Now we need to create a login page, note the location in the ErrorDocument 401 from Step 3.  Whenever a browser attempts to enter a /private url they will be directed to this page to login if they are not logged in.

So we create /login.html –

<html>
    <head>
        <title>Login page</title>
    </head>
    <body>
        <form method="POST" action="">
            User: <input type="text" name="httpd_username" value="" />
            Pass: <input type="password" name="httpd_password" value="" />
            <input type="submit" name="login" value="Login" />
        </form>
    </body>
</html>

Note the POST action goes to nothing, Apache will resolve that action upon login to return the user to whichever page they attempted to visit in /private before being redirected to the login page.

Step 5: Create a username and password using htpasswd.  You may need to create a directory and file for this, depending on your system settings, for htpasswd to be able to write to. Note the AuthUserFile setting from Step 3 as to where this file will be.

htpasswd -c /path/to/auth/.htpasswd myusername

htpasswd will prompt for a password and that username/password will be saved to the .htpasswd file. This username and password will then be used for logging in to your secured area.

Step 6: Restart httpd and try it out!  If you have trouble at this point, refer to the resource I used for the instructions up to this point:  http://melandri.net/2012/04/29/using-apache-mod-auth-form/

Now, after you login using Chrome or Firebug, bring up developer tools for the webpage and inspect the cookies. You’re not going to like what you find.  Your username and password are stored in your cookie in plain text. There are options, one is to store the session data server side and deliver the session as a session ID to the browser.  The other is to encrypt your cookie so that the cookie data is just a bunch of cypher data.

Session: Reserved Area-user=user&Reserved Area-pw=password

Now consider the fact that instead of htpasswd for user authentication, maybe you are using mod_auth_ldap – which uses your domain active directory credentials (Perhaps an article on integrating websites with LDAP in the future).  You’ve just potentially stored sensitive data in your browser in plain text, in a cookie.. which, other websites can potentially see.  So we’re LoadModule session_crypto_module modules/mod_session_crypto.sogoing to append to this tutorial mod_session_crypto.

Step 7: Add or uncomment crypto module in your httpd.conf from Step 1.

LoadModule session_crypto_module modules/mod_session_crypto.so

Step 8: Add a crypto directive to your protected directory in httpd.conf from Step 3.

SessionCookieName session path=/
SessionCryptoPassphrase secret

Step 9: That’s it, restart apache and login again. Check your cookies and you should see something more like this.

session=RG7qwUA9TD+M4MKkJ3sYdGcHog+1eTqlUVOzAZNNNmVtg9yoCMqpioTu/Jr3hdx86HQxYb7.....

There is a lot more that can be done, like;

  • using LDAP or other methods of authentication that tie in with existing services that you may already have.
  • using a session secret file or command to have more unique passphrases for the session crypto.
  • create login/out handlers for your session.
  • run the whole thing in SSL.

But those are all topics for another day, until then check the Apache website for more information.

 

 

2 thoughts on “Apache mod_auth_form & mod_session_crypto.”

  1. Great article, I like mod_auth_form. I also ran into the plaintext passwords, was horrified, and found the SessionCrypto solution. Unfortunately, now I cannot find a way of determining the logged in user name from php. I used to look in the cookie when it was plain text for the username, but now it is encrypted (the whole cookie string) . I thought the cookie was supposed to be decrypted automatically by Apache and SessionCrypto before it gets to php, but no… Any Ideas (REMOTE_USER and PHP_AUTH_USER are not set either 🙁 )

  2. I found this thread – Decrypting mod_session-created cookie and what I garner from the information available is that you would have to decrypt the session yourself. Ref: Apache Docs. In that thread someone does have some PHP that supposedly can handle that, but I haven’t personally tested it out. Best bet perhaps in this situation is to store the cookie server side and simply pass the browser a session ID. I’m not as familiar with that method, I believe mod_socache_shmcb.

Leave a Reply

Your email address will not be published. Required fields are marked *