restful_authentication and the Apache ACL

Wow, it didn’t take long after setting up this blog to find a coding issue that warranted blogging about. This is a real slap forehead WTF moment as well. I’ve been using the restful_authentication plugin for rails to handle my user registration and login. This is for a new site which will be announced shortly.

The site is currently sitting on a live server somewhere, so I decided to set up an Apache ACL while we have a closed beta test. An ACL is a way to get Apache to use basic authentication and log people in against a password file on the web server. It’s a quick way to lock down a site for a bit. See the bottom of the post for how to set up an ACL.

I sent around the ACL username / password to a few people, let’s say the username was pingu for argument’s sake. Well, the first person to use the site not only logs in to the ACL with pingu, but used it as a username to register on my rails app. Big deal you might think, I can’t imagine it would hurt. That would be your first (and my) mistake.

Somehow, the ACL interacted with restful_authentication so that anyone logging in to the ACL was also logged in to pingu’s rails account. I clearly don’t know enough about http authentication or the restful_authentication plugin but that is definitely unintended circumstances. Changing the ACL username put everything back to normal. Let’s hope no-one registers with the new ACL username!


edit – Setting up an ACL

I notice a few people got here after searching for ACL details so here’s a quick guide to setting one up. I’ve assumed your Apache instance is installed under /usr/local/apache, if it’s not then please replace /usr/local/apache with the appropriate path in the commands below.

Create a password file using htpasswd

The first step is to create a password file which defines usernames and passwords. This is done using the Apache supplied tool htpasswd (typically this lives in /usr/local/apache/bin). A good place to put your password file is /usr/local/apache/passwd/, although it can go anywhere Apache is able to access. Note that although this file has basic tampering precautions, typically MD5 hashing, it is not entirely secure and should be kept very secret from the rest of the world. So, move into your desired password directory, in our case /usr/local/apache/passwd/ (create it if it does not exist), and run:

/usr/local/apache/bin/htpasswd -c passwords myusername

This will overwrite any existing password files called “passwords” so ensure it doesn’t already exist. The c switch means create, passwords is the name of the file and myusername is the username of a user to add. It will prompt you for a password twice which will be set on the user “username”. To add new users, just remove the c switch (forgetting to do this will overwrite all previous users), i.e. run

/usr/local/apache/bin/htpasswd passwords anotheruser

Configuring a Location with AuthType

Typically an ACL is applied against a Location under a VirtualHost element. So, let’s say you want to lockdown an entire site for beta testers only. In the Apache configuration file httpd.conf (typically under /usr/local/apache/conf), find your VirtualHost element for the site you want to lockdown and add:

<Location "/">
    AuthType Basic
    AuthName "Authorised beta testers only"
    AuthUserFile /usr/local/apache/passwd/passwords
    Require user myusername
</Location>

The “/” specified by location means everything under the root directory of the site is password protected. If you just had some content, e.g. under a directory called protected, you could specify “/protected”. AuthName is the title of the prompt that the browser will bring up, AuthUserFile is the password file we created earlier. Require user specifies which users are allowed through. If you would like to allow all users in the password file through, you can specify Require valid-user instead. Restart Apache and every time you try and access something under the Location specified, your browser will prompt you for your username and password.

Leave a Reply

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