- Taint Mode
In addition to some sort of user authentication, nothing beats good 'ol taint mode. If you're dealing with CGI, just use
#!/usr/bin/perl -wT
at the top of your Perl scripts. If you're in mod_perl, you need add the following line to your httpd.conf:
PerlTaintCheck On
Taint mode forces you to clean up data that was received from an outside source, before you can do anything too damaging with it. To untaint data, you just have to send it through a regex.. if it matches, the resulting $1 will be untainted. Yes, it is possible to write cheesy regexes to get around this, but then that's the programmers fault for not trying.
You can get all sorts of juicy bits of information on taint mode, and other security measures, with "perldoc perlsec". Additionally, there are two modules, taint and untaint which are utility functions for working in taint mode. You don't need them, but they may prove helpful depending on what you are trying to accomplish.
- Password Challenge-Response
It's also possible to keep from sending plaintext passwords when you have no SSL. It's called a challenge-response system. In order to make it work, you need something like a javascript md5 implementation on the client end, and session support and md5 on the server end.
When the browser connects to the server for the first time, a new session ID is generated for it. Additionally, a hash is generated (made of random characters, much like the session ID). The session ID and Hash are stored on the server, AND given to the browser on it's first request (which is probably the login page).
Whenever the user types in their name and password, and then clicks submit.. you have the HTML form call a javascript function BEFORE it submits any data to the server. The Javascript function MD5's the password, and appends the result to the Hash that we generated earlier. Then you MD5 the resulting string. This resulting string is what you send to the server as your password. Immediatly replace the plaintext password with this new string you have, you don't want the plaintext password going to the server :-)
When the form finally submits the info to the server, your server does the same process. It digs the users password out of the database (or whatever you are using), runs it through MD5, appends that to the hash it has associated with your Session ID, and then runs the resulting string through MD5. Now, if that matches what the browser passed you, the password is correct!
This method isn't the most secure method in the world, by any means. SSL would be better then this. For even better protection SSL could be used in addition to this method. But as you said, SSL isn't always available. If somebody is sniffing your connection and you don't have SSL, they can sniff the hash that the server sent you. Now, they would never ever see the password in plaintext. But with the hash, they might have a better chance at being able to brute force your password. Would it be easy for them to do this? No. But if somebody really wanted to break in, that would be a possible route they could use. Just something to ponder...
-Eric
Updated
| [reply] [d/l] [select] |
Without encryption, no simple form of password authentication is secure. The client's entries or cookies are in the open to be sniffed.
Get SSL or change servers. If this is in-house, and the budget won't cover security, you can set up a Linux box from a surplus 486 to act as a front end. You may need to keep it a secret.
There are boatloads of modules on CPAN to help do this given a sane environment.
After Compline, Zaxo
| [reply] |
Look into one-time password schemes using S/Key. (I think there are
Perl modules the handle this, like Crypt::SKey.) It works the following way:
- You and the user have a share secret passphrase.
- When the user first logs in, she is asked to provide
a challenge password based on N MD5-iterations of the
passphrase (S/Key converts the MD5 hex digits into
a small group of 3-5 letter words so it's easy for a user
to type)
- Each time the user logs in, the password is based on
N-1 iterations. So there's no way a hacker could determine
this (well, a crypto guru with that knowledge probably
won't care to hack your web site since some three letter
agency is paying her big money to do more interesting
things ;)
- When it nears zero, the user resets the passphrase to
something different. (Usually initial N is something like
1000)
Information on S/Key can be found at http://lheawww.gsfc.nasa.gov/~srr/skey_info.html.
| [reply] |