Secure login & sessions, how secure?

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
TomasTrek
Forum Newbie
Posts: 6
Joined: Tue Aug 19, 2008 8:44 am

Secure login & sessions, how secure?

Post by TomasTrek »

Im trying to make a secure login for my site, so that only members can access the data. The data in question is my geographic position on a map - so I would like for it to be as secure as possible. I want to expand this so that other people can put their own positions on and then use their login details to see their update history.

So I have spent a while looking up PHP secure login examples/texts/discussions, and come up with some code. I would appreciate it if someone could scan it over and look for any obvious vulnerabilities in it. As well as that, I now have the problem of keeping the user logged in. I have read that it is possible for an attacker to spoof a session id, so I am not sure on what is the most secure way to do this. I thought that after login I could set some session variable isAuthed to 1 and then check this on subsequent pages. But if the session can be hijacked then wont this be useless? Storing the username and password in the session would be similarly useless in such a case too wouldnt it? As if someone steals a session id, then as far as the server is concerned then it is the correct user, and as sessions are on the server everything would authenticate fine. That is my assumption/conclusion anyway, I could be wrong. Is there a good article I can read that will clarify these?

My login code currently looks like this:

Code: Select all

 
<?PHP
    $u=$_POST['uname'];
    $p=$_POST['pword'];
 
    if($_SERVER['HTTP_REFERER'].'=='.'http://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\').'/login.php')
    {
        if($u&&$p)
        {
            $u=strip_tags(stripslashes($u));
            include("../../func/uchk.php");
            $u=mysql_real_escape_string(htmlentities($u));
            $q = mysql_query('SELECT regtime, uname, pword FROM rdusers WHERE uname=\''.$u.'\' LIMIT 1');
            $r = mysql_fetch_row($q);
            mysql_close($c);
            $q = NULL;
            $c = NULL;
            $p = crypt(md5(crypt(sha1($p),$r[0])),$r[0]);
 
            if($u==$r[1]&&$p==$r[2])
            {
                $u=NULL;
                $p=NULL;
                $r=NULL;
                //init session
                
                header('Location: http://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\').'/main.php');
                exit;
            }
        }
    }
    header('Location: http://'.$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\').'/login.php');
?>
 
uchk.php only does the following:

Code: Select all

<?php
$c = mysql_pconnect('<host name here>','<username here>','<pword here>') or trigger_error(mysql_error(),E_USER_ERROR); 
 
mysql_select_db('<db here>',$c);
?>
The sql user I am getting the details with can only SELECT, so the database should be safe at least during login. It is also above the web accessible area of the server and has a .htaccess file, plus an index.php to stop the directory listing being shown. As far as I know, and as far as I have read, this should be secure. To be honest my main concern now is the sessions, as I dont know what the most secure way to use them is going to be. If anyone could provide some help I would be extremely grateful.

Thanks,
Tomas
nowaydown1
Forum Contributor
Posts: 169
Joined: Sun Apr 27, 2008 1:22 am

Re: Secure login & sessions, how secure?

Post by nowaydown1 »

Greetings Tomas,

Welcome to the forum! I can't really comment on the vulernability side of the code you posted, but I can contribute something on the session side. I would check out:

http://phpsec.org/projects/guide/4.html

The article goes over session hijacking / fixation attacks and some ideas for preventing them. There's also a few security guru's floating around. Hopefully one of those guys can chime in on the code you posted.
TomasTrek
Forum Newbie
Posts: 6
Joined: Tue Aug 19, 2008 8:44 am

Re: Secure login & sessions, how secure?

Post by TomasTrek »

Thank you for the welcome and very speedy response. I read the article and it makes a good point, I have changed my code now to include these suggestions.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Secure login & sessions, how secure?

Post by Mordred »

I don't see any session code, so I can't comment on that.
The SQL handling code looks secure, although it does some unneeded things like stripping slashes, tags and doing htmlentities.

I don't like that you open and close a db connection especially for the login check, it's inefficient.

The multiple hashing scheme is a bit of an overkill, but in such small scale it doesn't matter.
Salting the hashes is good, but you might check this article for a slightly better option: viewtopic.php?t=62782
avirup
Forum Newbie
Posts: 12
Joined: Mon Sep 15, 2008 3:07 pm

Re: Secure login & sessions, how secure?

Post by avirup »

Can Anybody will check this code ...as I am new to this session...
Please tell me what code make this much more secure.

Code: Select all

<?php 
session_start();
require("functions.php"); ?>
<?php
//connecting to the database
dbconnect();
 
//fetching data from the form 
$uname=check_input($_POST['username'],"Please enter your name");
$pword=check_input($_POST['password'],"Please enter your password");
 
//fetching data from the database 
$result=mysql_query("SELECT * FROM `login_user`           
                             WHERE `username`='$uname'") or die(mysql_error());
                             
$row=mysql_fetch_array($result);
$un = $row['username'];
$pw = $row['password'];
$uid= $row['user_id'];
 
//Date 
$today = date("F j, Y, g:i a");
 
//ip address fetching
$ip=getenv("REMOTE_ADDR");
echo "$ip";
 
//setting the lifetime of a session
ini_set("session.gc_maxlifetime", "18000"); 
 
//checking the user input with the database table
if(($un==$uname)&&($pw==$pword)) 
{
$_SESSION['suname'] = $un;
$_SESSION['spw'] = $pw;
$_SESSION['suid'] = $uid; 
$_SESSION['sip'] = $ip; 
 
$ret = mysql_query("INSERT INTO `fcdb`.`member` (`user_id`, 
                                          `uname`,
                                          `pwd`,
                                          `ip`,
                                          `j_date`)  
                    VALUES ('$uid',
                            '$un',
                            '$pw',
                            '$ip',
                            '$today')") or die(mysql_error());
}
 
if((!session_is_registered('suname'))&&(!session_is_registered('spw'))) 
{
header("location:error_login.php");
}
else
{
header("location:user_home.php");
}                       
?>
 
 
Post Reply