Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
login script - tips/security

Posted by dabbler (leah), 24 October 2003
After lots of time spent on php.net, I finally got somewhere with the login script I was working on. It's not done, as it's not setting yabb cookies yet, that's the easy part, I'm not so much worried about that bit. I'm concerned about security. What should I be doing to make this as secure as possible?

My login testing page:
Code:
<?php

// Set variables here.
$memberdir = "/path/to/yabb/Members/";
$variabledir = "/path/to/yabb/Variables/";
$cookiedomain ='mysite.com';

    function checkAuth($userToCheck, $passToCheck) {
    global $memberdir;
     $username = $userToCheck;
     $filename = $username.".dat";
     $datafile = $memberdir.$filename;

    if (file_exists($datafile))
            {
            $handle = fopen ($datafile,"r");
            $content = trim(fgetss($handle, 20));
            $encodedPass = crypt($content,yy);
            }

        if ($passToCheck == $encodedPass) {
            $check = TRUE;
        } else {
            $check = FALSE;
        }    
        return $check;
       
    }
     
    function CheckBanlist ($username)
     {
     global $variabledir;
     $banlistfile = $variabledir."ban.txt";
     $handle = fopen ($banlistfile,"r");
     $banlistip = explode("\n",(fread($handle, filesize($banlistfile))));
     fclose($handle);
     $client_ip = getenv ("REMOTE_ADDR");
     foreach($banlistip as $ipaddress)
           {
           $banned = strpos("$ipaddress","$client_ip");
           }
     if($banned === TRUE)
     { return FALSE;
     }
     
     else {
     $userbanfile = $variabledir."ban_memname.txt";
     $handle = fopen ($userbanfile,"r");
     $userbanlist = (fread($handle, filesize($userbanfile)));
     fclose($handle);
     $userbanned = strpos("$userbanlist", "$username");
     if($userbanned !== FALSE)
     { return FALSE;
     }
     else { return TRUE; }
     }
}
     
    if (isset($logout)) {
        setcookie ('cuser', "",time()-3600, '/',$cookiedomain);
       setcookie ('cpass', "",time()-3600, '/',$cookiedomain);
    }
   
    if (isset($login)) {
       $password = crypt($formPass,yy);
       $username = $formUser;
       
       if (checkAuth($username, $password) && CheckBanlist($username)) {
           setcookie ('cuser', $username,time()+3600, '/',$cookiedomain);
           setcookie ('cpass', $password,time()+3600, '/',$cookiedomain);
           $msg = "Authentication was successful! The cookies have been set!";
       }else{
           $msg = "Authentication error!";
       }
    }
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<?php
           if (isset($login)) {
               echo("<meta http-equiv='refresh' content='5;url=$PHP_SELF'>");
           }
       ?>
<title>Test Cookie</title>
</head>
<body>
<?php
   
       if (isset($cuser) && !isset($logout)) {
           if (checkAuth($cuser, $cpass)) {
               echo("<p>Hello $cuser!</p>" .
                   "<p>Your password (encrypted) is: $cpass</p>" .
                   "<p><a href='$PHP_SELF?logout=1'>Delete cookies and force login<a></p>");
           }
//                  else {
//                echo("<p>Authentication error from cookies values</p>" .
//                    "<p><a href='$PHP_SELF?logout=1'>Delete cookies and force login<a></p>");
//            }
       } else {
       
           if (!isset($login) || isset($logout)) {
           echo ("<form action='$PHP_SELF?login=1' method='POST'>".
               "<p>User: <input type='text' name='formUser'></p>".
               "<p>Pass: <input type='password' name='formPass'></p>".
               "<p><input type='submit' name='submit' value='Log In'></p>".
           "</form>");
                 
           }
                 elseif (isset($login)) {
               echo("<p>$msg</p>" .
                   "<p>You'll be redirected in 5 seconds!</p>");
          }
       }
       ?>
</body>
</html>


Any other tips on improvements?

Many thanks.

Posted by admin (Graham Ellis), 25 October 2003
Good Morning ...

"How secure is my script?" issues relate not only to the code itself, but also to the server environment.  So - first things - be careful that there isn't a backup copy of your script on your server with a different extension so that hackers can see a copy of your source, and (perhaps) move most of the PHP code into a different file that you include from a different directory off your document path.  Also (if you're on a shared server) check that you have permissions restricted against other users of the same server. These first things are "back door" checks; a thief will tend to see if the back door is open before he goes to the touble of trying to break in at the front.

Now ... the front door.  
a) Your script uses global variables from the form (such as $formUser); will work on most ISPs and on PHP up to 4.1.2 by default.  I suggest you switch to the superglobal arrays; a direct replacement would be $_REQUEST["formUser"] and the code should then work on PHP 4.1.0 and later, no matter how the configuration is set.
b) I would force the data to be accepted only through a POST and not through a GET - so use $_POST["formUser"], etc.   If you accept "get" data, you are allowing users to set up a link that logs them in directly, and your script will also allow people to provide a spoof login page that would reveal the password in the location bar.
c) Again, to clean up the URL, I would suggest that you move "login" to a hidden field rather than having it as GET parameter
d) I'm a little concerned at the "yy" salt.  Is that really what Yabb uses? If it does, it makes it much easier for anyone who can get a copy of your login files through some accidentally open security hole to run a dictionary-based attack looking for user's passwords.

Please don't be put off by the above ... you *did* ask how to make it "as secure as possible", and as it stands it looks pretty good anyway.  By the way - you aren't going to echo out their encryted password in the live system are you?


Posted by dabbler (leah), 25 October 2003
Quote:
By the way - you aren't going to echo out their encryted password in the live system are you?


No no no, that was part of the original cookie setting script I had found, and it helped me with the salt and testing.

Quote:
I'm a little concerned at the "yy" salt.  Is that really what Yabb uses?


Afraid so. Maybe this will change in upcoming versions. If not, I may address it then, make some modifications.

Thank you for the great tips Graham, much appreciated.



This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho