[thelist] Root and .htaccess

Keith cache at dowebscentral.com
Mon Jul 21 21:53:26 CDT 2003


At 08:01 PM Monday 7/21/2003, you wrote:

>we have a .htaccess file in the main directory of the site that points
>to a users file containing all usernames and shadowed passwords. You add
>users to this list by logging on to root and executing the _htpasswd_
>command with the proper parameters.

Both A & B are BAD practice IMHO.

Never give root access to someone who is not a principal in the company or 
the superuser employee. It's not just bad security, it's a really bad 
business practice. Ask the owner, "When things go bump in the night, and 
they do, do you want to suspect an employee or find the problem?"

You do not need root access to create a password. Linux and Perl use the 
same MD5 crypt() function to encrypt passwords. Your .htaccess file does 
not need to read the username:password from the usertable for Linux access. 
In fact, that's why .htpasswd exists, for basic authentication you simply 
put the .htpasswd file in the same directory as your .htaccess file. In 
your .htaccess file tell it where to find the password file with:

AuthUserFile  /absolute_path_to/protected_directory/.htpasswd

To keep the .htpasswd file private add

<files .ht*>
Order allow,deny
Deny from all
</files>

to your .htaccess file. That denies access to the file via the browser, and 
makes it just as secure as the Linux password file (which can be read by 
any user on the box).

Create an HTML form with two fields: name=user & name=password

Submit to the following Perl script with POST method (you don't want that 
password value hanging around in a query string in the location field, 
history, etc)

=================================================
#!/usr/bin/perl

$htpasswd_file = "protected_directory/.htpasswd";

read(STDIN, $input, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/,$input);
foreach $pair (@pairs){
   $pair =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
   ($name, $value) = split(/=/,$pair,2);
   $value =~ tr/+/ /;
   $value =~ s/~!/ ~!/g;
     if ($value =~ /[;><\*`\|]/){exit}
$$name=$value;
}

$salt = substr($user,0,2);
$PASSWORD=crypt($password,$salt);

open(HT,">>$.htpasswd_file");
print HT "$user:$PASSWORD\n";
close(HT);

print "Content-type: text/html\n\n";
print "USER $user was added";

======================================================

Unless you are going to have more than 1,000 users on this one .htpasswd 
file, don't waste your time and your client's money databasing the user 
names. I run up to 5,000 per .htpasswd before beginning to see any 
degredation. But keep this in mind when deciding whether to database or 
not, every request made to a Basic Authentication directory goes through 
authentication. A page with 5 images inside that directory tree gets 6 
authentications - put the images outside that tree unless they are what you 
are protecting.

FWIW, the above layout of putting the .htaccess and .htpasswd file in the 
same directory passes both VISA and HIPPA security requirements.


Keith
====================
cache at dowebscentral.com



More information about the thelist mailing list