--- Ryan Davis <[EMAIL PROTECTED]> wrote:
> Hey all,
>
> I have a password protected area, and after the user puts in their password, I store
>it in a
> cookie, and the CGI reads that cookie every time to determine if the user is logged
>in or not.
> I figured this was safer than passing a 'loggedin' param as a hidden field, but I'm
>not sure if
> there is an industry standard way to do this. My code is too long (300+ lines, and
>messy), so
> here's the outline/psuedocode:
>
>
> #try to snag the cookie
> $pw = get_cookie()
>
> #if the user is logging in for the first time, write the cookie
> if($cgi->param("password"){
> $pw = $cgi->param("password");
> write_cookie($pw);
> }
>
> #set a boolean if the password is correct
> $loggedIn = isCorrect($pw);
>
> unless($loggedIn){
> prompt_for_password();
> }elsif(
> ...rest of program
>
>
> Is this secure? Is there a better way to do this?
>
> Thanks,
> Ryan
Ryan,
Storing passwords in cookies is very insecure. There are often a number of ways to
get to the
data in a cookie. Running a packet sniffer is one. Some sites allow users to sign up
and post
information to the site. These pages often have user-supplied javascript and that can
be used to
grab cookies.
A better way of handling this is to create a *digest* of the password. With this
method, you
create a string of characters that can be computed from the password, but the password
cannot be
computed from the characters. It is mathematically very unlikely that two different
passwords
will ever generate the same digest (much less likely than two people choosing the same
password.
Here's a subroutine that will do what you need. It creates a 22 character digest from
a password.
I've taken this from one of my programs and modified it for you. It's pretty much
cut-n-paste
into your code (which is why it's not the most efficient way of doing this).
sub create_digest_from_password {
my $pass = shift;
use Digest::MD5;
my $md5 = new Digest::MD5;
my $rand = '%doM4)#-<';
$md5->add( $pass );
$md5->add( $rand );
return $md5->b64digest;
}
Note the $rand variable. What this is for is to add a completely random string to the
password.
That way, if someone figures out that you're using md5, they can't just "brute force"
the password
by guessing at the password. They'd also have to figure out the random string.
Also, in my actual code (which is a bit more complex than what you see here), I DO NOT
HAVE $rand
HARD-CODED IN THE PROGRAM!!!! This is a biggy. If someone gets your source code, all
bets are
off. What I do is put the value of $rand in a file in a non-Web accessible directory
and have my
program read it in. That way, it's never explicitly in the code.
Incidentally, our databases also do not have passwords in them. We use a technique
similar to
what's above. If, for some reason, we were to lose the $rand, we wouldn't be able to
verify any
passwords. It's an inconvenience, but security and convenience are mutually exclusive.
Cheers,
Curtis Poe
=====
Senior Programmer
Onsite! Technology (http://www.onsitetech.com/)
"Ovid" on http://www.perlmonks.org/
__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]