I have a PHP script that runs as a CGI program and the HTTP Authenticate header gets eaten and spit out. So I would like to implement some kind of FORM based authentication. As an added constraint, there is no database so no session data can be stored.

I am very open to having a master username and password. I just need to protect the application from an intruder who doesn't know these credentials.

So how would you implement this?


I could present the form and if it validates, I can send back a cookie that is a hash of the IP address come secret code. Then I can prevent pages from rendering unless the thing decrypts correctly. But I have no idea how to implement that in PHP.

+2  A: 

A few ways you could do this.

  1. htaccess -- have your webserver handle securing the pages in question (not exactly cgi form based though).
  2. Use cookies and some sort of hashing algorithm (md5 is good enough) to store the passwords in a flat file where each line in the file is username:passwordhash. Make sure to salt your hashes for extra security vs rainbow tables. (This method is a bit naive... be very careful with security if you go this route)
  3. use something like a sqlite database just to handle authentication. Sqlite is compact and simple enough that it may still meet your needs even if you don't want a big db backend.

Theoretically, you could also store session data in a flat file, even if you can't have a database.

Justin Standard

... About salt, add the username in your hash salt will prevent someone who knows your salt and have access to your password file to write a rainbow table and crack number of your users's password.

+1  A: 

If you're currently using Authenticate, then you may already have an htpasswd file. If you would like to continue using that file, but switch to using FORM based authentication rather than via the Authenticate header, you can use a PHP script to use the same htpasswd file and use sessions to maintain the authentication status.

A quick Google search for php htpasswd reveals this page with a PHP function to check credentials against an htpasswd. You could integrate it (assuming you have sessions set to autostart) with some code like this:

// At the top of your 'private' page(s):
if($_SESSION['authenticated'] !== TRUE) {
 header('Location: /login.php');

// the target of the POST form from login.php
if(http_authenticate($_POST['username'], $_POST['password']))
 $_SESSION['authenticated'] = TRUE;
John Douthat
+1  A: 

Do you really need a form? No matter what you do, you're limited by the username and password being known. If they know that, they get your magic cookie that lets them. You want to prevent them seeing the pages if they don't know the secret, and basic authorization does that, is easy to set up, and doesn't require a lot of work on your part.

Do you really need to see the Authorization header if the web server takes care of the access control for you?

Also, if you're providing the application to a known list of people (rather than the public), you can provide web-server-based access on other factors, such as incoming IP address, client certificates, and many other things that are a matter of configuration rather than programming. If you explained your security constraints, we might be able to offer a better solution.

Good luck, :)

brian d foy