Database backed web applications: security issues

The functionality that checklist makes available is not necessarily something you want to make available to everybody. The WWW security mechanisms can be used to protect these functions. Apache allows protections via URL with the location directive, which would look something like this:

<Location "/cgi-bin/checklist.py/">
	AllowOverride	None
	Options		None FollowSymLinks

	AuthName		"Hotlist Maintenance"
	AuthType 		basic
	require			group hotlist
</Location>

This causes all references to any URL that starts with /cgi-bin/checklist.py/ to use the HTTP basic authentication scheme to get a userid and password from the browser with the name Hotlist Maintenance, and requires that the user be in the group admin. This is the standard WWW security mechanism.

The part of this that's missing is where the userids, passwords and group information come from. The configuration of Apache that builds out of ports uses flat text files for this information. This is fine for some cases. If you want to allow users to do maintenance on their own ids, you might want a web interface for that. This means you're going to have a list that's updated over the web. If the list is large, you might want something that provides faster access than a flat text file. Both of these point to using a database. For web authentication, you do not want to create flat files from the database, but to access it directly.

One of the strengths of Apache is the selection of modules available for it. This strength comes into play here - because Apache has a module for accessing authentication information in PostGreSQL, mod_auth_pgsql. Similar modules exist for most popular databases. The downside of that strength is that the configuration of these modules needs to be done at the source level. The number of these modules means that the ports collection is unlikely to have just the configuration of Apache that you want. The default configuration of Apache includes a module set that is suitable for most people - but not in this instance. mod_auth_pgsq isn't built in that server.

The difficulty of configuring modules at the source levels has led to a number of different methods of doing so, ranging from editing the Apache src/Configuration file by hand, to the apxs command. What works for which modules is usually documented in the module in question, and which any given person prefers will depend on that person. I normally just edit the Configuration file, as that works for all modules, and allows the greatest control of the configuration. You should read the documentation for the modules, and the Configuration file, and decide for yourself which you want to use.

After you've built an Apache server with mod_auth_pgsql in it, and run that server (note: apachectl restart will not work - you must use apacehctl stop and apachectl start to start a newly compiled server!), you need to create a user database. A typical schema might be:

create sequence user_counter ;

create table users (
	name		text ,		// just a name
	password	text ,		// a clear-text password
	unique ( name )
	) ;

create table groups (
	name		text ,	// the users id, from users
	groupname	text ,		// the group name
	primary key ( name, groupname ) ,
	foreign key ( name ) references users
	) ;

Given that schema in a database - say web - then the Location directive would be:

<Location "/cgi-bin/checklist.py/">
	AllowOverride	None
	Options		None FollowSymLinks

	Auth_PGhost		localhost
	Auth_PGport		5432
	Auth_PGdatabase		web
	Auth_PGpwd_table	users
	Auth_PGuid_field	name
	Auth_PGpwd_field	password
	Auth_PGgrp_table	groups
	Auth_PGgid_field	groupname

	AuthName		"Hotlist Maintenance"
	AuthType 		basic
	require			group admin
</Location>

The above provides an outline for setting this up. For any usage more complicated than protecting one URL, you will probably want a more complex schema, and some form of application code running on it. For instance, the typical registered user database one sees on many web sites could be built from this foundation, but that's a different paper. If you're interested in such a thing, contact me, as I may have one.

Having the application working and properly protected, it's time to look at improving it's performance.


Prev, Next, Contents

Mike Meyer,
March, 1999