http://qs1969.pair.com?node_id=62376

SilverB1rd has asked for the wisdom of the Perl Monks concerning the following question:

I'm setting up an admin section for my site and I want to make sure no one can find my user names and passwords. Is there any special file types I should use or stay away from? Do I need to encript the file or would this be overly redundent?

------
The Price of Freedom is Eternal Vigilance

Replies are listed 'Best First'.
Re: Best way to hide passwords.
by tadman (Prior) on Mar 06, 2001 at 04:30 UTC
    If you're using a '.htpasswd' style system, use MD5 crypt instead of DES. MD5 is much harder to crack than the simple DES encryption used by default, and it's perfectly compatible, at least when it comes to using Perl and crypt(). More on that in a second.

    If you are storing passwords on your system, you want to ensure that even if the file should fall into the wrong hands, there is no easy way into your system. This is effected by having the passwords stored encrypted, just like they are in the UNIX '/etc/passwd' file (or, '/etc/shadow' which is more common these days). Since the passwords are sent via HTTP or a cookie, or some other mechanism in a non-encrypted way (even over "encrypted" SSL, they are decrypted into plain-text by the server for authentication), the encrypted passwords are no use since you still don't know the password to gain access.

    As distributed.net proved, DES encryption is quite flimsy and hardly provides any security at all. You should use MD5 instead, which is a much more robust algorithm.

    The trick to using MD5 instead of DES is in how you supply the "salt" to the crypt() function. If you follow the docs, you would supply two random letters. For MD5, you use eight, which allows for more variations when it is stored encrypted, which translates into better security.

    Here's a standard-issue MD5 salt generator:
    my (@chars) = ('a'..'z','A'..'Z','0'..'9','.','/'); sub md5_salt { my ($return) = '$1$'; $return .= $chars[rand($#chars+1)] foreach (0..7); return $return; }
    It is used just like always:
    $encrypted_passwd = crypt($passwd, md5_salt()); # For testing... if (crypt($passwd_guess,$passwd_encrypted) eq $passwd_encrypted) { # Got it. }
    So you get passwords that are encrypted like:
    $1$1PUXLuZE$P.LfclRO9SKqTf2BQK.yD1 $1$t7AJPueY$1ivH/pIhxnjEIx10QzaIi. $1$lvWzTNnn$JFsfy9ALLJS3Dpi4OHMVo1
    Which are, incidentally, all the same password ('shjdajksds') with different "salt".

    If you are using a database, such as MySQL, you could use the built-in PASSWORD() function which does the encryption for you. Or, you could use your own. It depends on the security of your application.

    What you should not ever do is store passwords as plain-text. So, yes, encrypt the passwords in the file, but don't bother encrypting the whole file.
      Note for Windows folks: getting crypt to supply MD5 encryption as described by tadman is not supported in ActiveState Perl.
      print "Long: ", crypt('shjdajksds', '$1$abcdefgh'), "\n"; print "Short: ", crypt('shjdajksds', '$1' ), "\n";
      Using ActiveState build 623 this produces:
      Long: $1G0qFXI2hLqU Short: $1G0qFXI2hLqU
      But on Linux we get:
      Long: $1$abcdefgh$LBpJSL4DEIVrkp1RZO36I0 Short: $1KHjUeDByb1c
      As is often the case YMMV. (Can we assume that Linux Perl is calling a system function which supports the MD5 option?) The standard Perl doc page for crypt doesn't mention this behavior. Nor does   'man crypt'   on my Linux system.

      Where is it documented?

      And I don't even want to talk about why the short versions are different on the two systems. Yuck! (I ran this several times to be sure.) Are 'standard' passwords not sharable across platforms?

Re: Best way to hide passwords.
by wardk (Deacon) on Mar 06, 2001 at 03:34 UTC

    Not much to go on, I will assume to want to have your own user/pw file and manage them yourself via CGI.

    First off, if on unix, make the file permissions 600, so that you and only you can even read them.

    As far as users getting logged in, there are multiple nodes here on passing passwords, maintaining state, sessions, etc, etc. Some quick searching should get you squared away quickly.

    Be careful with this! (take all the warnings you get here to heart, you're likely gonna get a handful!)

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Best way to hide passwords.
by cleen (Pilgrim) on Mar 06, 2001 at 05:30 UTC
    In my opinion, I think you should use a centralized authentication based system like kerberos. Why? With linux/bsd varients you can use Authen::PAM to authenticate against kerberos using pam. While one of my favorites (does REAL kerberos calls) is a module for apache called "Mod auth Kerb". It allows you to have a default realm, and you can utilize kerberos within a .htaccess password prompt.

    check out:This! for the apache mod.

    I have personally set this up, and it is a little bit of trouble (but not that much)

    Having an authentication system like this leads to 1) scalability 2) security 3) good solid programming api's.

    These days, redhat has made kerberosIV pretty much 'plug and play' and administration is very easy. I still suggest KerberosV, which has better security then 4.

    if you intend on having alot of users authenticating, this would be a good step to take.
Re: Best way to hide passwords.
by dws (Chancellor) on Mar 06, 2001 at 03:49 UTC
    If you're using Apache, put the file containing the password in a subdirectory, and add the following .htaccess file to that directory:
    Order deny,all Deny from all
    Voila! Nobody sees it.

    The only risk you have is that if one day you munge the .htaccess, the directory will be visible. tadman's advice below is sounder in that regard.

      Actually, the best thing, really the only thing to do is to make sure that your password file is not accessible from the Web at all! Don't put it in a directory that is served by Apache. Period.

      There have been many historical cases of people downloading your standard-issue '.htpasswd' file and running crack on it, finding dozens of simple passwords such as 'bob/bob', 'joe/123' and many others that would surprise you. These 'hax0rz' can do many unpleasant things to your Web site, and if you're not careful, there might be some system accounts with the same password and login as on the site...well, you know what happens next.

      So, if your script is running in "/site/www", put your data somewhere else, like "/site/data" which is not served by Apache.
Re: Best way to hide passwords.
by SilverB1rd (Scribe) on Mar 06, 2001 at 03:25 UTC
    Typo Correction"special file types" not "spechel file types"

    ------
    The Price of Freedom is Eternal Vigilance