Page 1 of 1

Login using sessions

Posted: Fri May 22, 2009 12:18 pm
by theorok
This post was accidentally deleted by the author.

In it, I asked about storing usernames and passwords, authentication using sessions and provided the following example scripts.

My apologies to those reading.

test.php

Code: Select all

 
  <?php
    session_start();
    
    //setup HTMLpurifier
    require_once 'purafier/library/HTMLPurifier.auto.php';
    $purifier = new HTMLPurifier();
    
    //handle input
    $quStr = $purifier->purify($_GET["aws"]);
    $tok = $purifier->purify($_SESSION['token']);
    
    
    if($tok != $quStr)
    echo'not logged in'; 
    else 
    echo'logged in'; 
    
    session_regenerate_id();    
    $key = md5(uniqid(rand(), TRUE));
    $key .= 'AVS1976JER1';
    $token = md5($key);
 
    $_SESSION['token'] = $token;
    $_SESSION['status'] = 1;
    
    $url = array();
    $html = array();
    $url['token'] = rawurlencode($token);
    $html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8');
    echo $html['token'];
    ?>
    
     <a href="test2.php?aws=<?php echo $html['token']; ?>">Click Here</a>
 
test2.php

Code: Select all

 
<?php
 
    session_start();
    
    //setup HTMLpurifier
    require_once 'purafier/library/HTMLPurifier.auto.php';
    $purifier = new HTMLPurifier();
    
    //handle input
    $quStr = $purifier->purify($_GET["aws"]);
    $tok = $purifier->purify($_SESSION['token']);
    $sta = $purifier->purify($_SESSION['status']);
        
    if($tok != $quStr && $sta != 1)
    echo'not logged in'; 
    else 
    echo'logged in'; 
 
    session_regenerate_id();
 
    $new_sessionid = session_id();
    $_SESSION['token'] = $new_sessionid;
 
?>
 
     <a href="test.php?aws=<?php echo $new_sessionid; ?>">Click Here</a>
 

Re: Login using sessions

Posted: Fri May 22, 2009 3:32 pm
by kaisellgren
theorok wrote:My question is, do I need to add login/password values to the session for a depth in defense approach
It will be the opposite - less secure. Do not store the username and the password anywhere except in their very original location. Only use them for the authentication process.
theorok wrote:

Code: Select all

$quStr = $purifier->purify($_GET["aws"]);
$tok = $purifier->purify($_SESSION['token']);
What is the point of doing that? Those variables are never even outputted, are they?
theorok wrote:

Code: Select all

$key = md5(uniqid(rand(), TRUE));
$key .= 'AVS1976JER1';
$token = md5($key);
The token is not very random.

Your test.php is vulnerable to UTF-7 (and probably to some other encodings) XSS attacks on line 33 and the same principle applies to the second file, too.

I'm not entirely following your code. It never checks for login credentials, does it?

Do not forget that the execution continues after you have echoed "not logged in".

Re: Login using sessions

Posted: Fri May 22, 2009 11:05 pm
by theorok
It will be the opposite - less secure. Do not store the username and the password anywhere except in their very original location. Only use them for the authentication process.
That makes sense. My goal is to understand the preferred way of authenticating a visitor on subsequent page using sessions instead of cookies. Once the login process is complete, is storing a "logged in" value of true in a session variable and evaluating this as true or false a viable solution for authenticating a user when they visit another page? If so, is passing the session id as a query string and comparing that to a value stored in another session variable a viable solution for determining the session is the same as the originating one? Is there another way I should consider instead of this approach?
What is the point of doing that? Those variables are never even outputted, are they?
I was outputting them for testing and had removed the echo's for simplicity of the example. However, my intention with this code was to filter these variables as input. From your response I infer this is incorrect, please advise why. I'm using HTML purifier to filter input and am new to that particular library, do you suggest against using this or have I misunderstood it's purpose in some way?
The token is not very random.
I've modified line 19 to use the following,

Code: Select all

$key = hash('sha256',$key);
as per feedback you've given in another thread. Is this satisfactory in terms of generating a random session id?
Your test.php is vulnerable to UTF-7 (and probably to some other encodings) XSS attacks on line 33 and the same principle applies to the second file, too.
I overlooked that as this was derived from a provided example. I believe I have fixed this but your other responses seem to indicate I may be incorrect. Will the following change remove the risk you describe above?

Code: Select all

 $tokenClean = htmlentities($url['token'], ENT_QUOTES, 'UTF-8');
?>
 <a href="test2.php?aws=<?php echo $tokenClean; ?>">Click Here</a> 
I'm not entirely following your code. It never checks for login credentials, does it?
You are correct. The functionality I am creating will reside after the username and password are validated against database credentials. The passing of the tokenClean variable via the hyperlink is used for simulating a user changing pages. I know I am reinventing the wheel here so to speak, but it's helpful in terms of learning about web application security in general.
Do not forget that the execution continues after you have echoed "not logged in".
Bitter irony at its finest. I really need to step away from the computer now. :)

Thanks for bringing these issues to my attention, and for your responses.

Tom

Re: Login using sessions

Posted: Sat May 23, 2009 8:45 am
by kaisellgren
theorok wrote:is storing a "logged in" value of true in a session variable and evaluating this as true or false a viable solution for authenticating a user when they visit another page?
Yes, you can do that. However, maybe you could store "logged in acp", "logged in mcp", etc instead of just "logged in" otherwise you don't know where he has logged into unless, of course, you have only one place where authentication is needed.
theorok wrote:From your response I infer this is incorrect, please advise why.
HTML Purifier helps you to protect from XSS attacks. Using it on variables that are never outputted is useless. I do not know what your code was before you posted it here, but it's always better to be paranoid and filter variables that do not need to be filter than to have XSS vulnerabilities, so, if you are unsure, better filter it, but if you know what you are doing, it will save your time and performance and probably makes debugging easier, too. You see, if you filter all variables, then you might get unexpected values at some point and you wonder why is something the way it is. It's just pointless to run the purifier on everything.
theorok wrote:I've modified line 19 to use the following,
Line 19? Line 19 is session_renegerate_id()... I'm not sure what did you replace now. I still not think your code generates random identifiers. If you are using it on a Unix -like platform you can very easily generate sufficient random data by reading /dev/urandom. Use fopen() and read as many bytes as you want. The more bytes you read, the more random data you get (the stronger). Then use an encoding function like base64 to be able to have it in a cookie/URL, because without encoding it contains non-printable characters.
theorok wrote:I overlooked that as this was derived from a provided example. I believe I have fixed this but your other responses seem to indicate I may be incorrect. Will the following change remove the risk you describe above?
No, that is not the problem. Your handling of data is ok, but you forgot something (or you did not know). The encoding must be specified. You are never telling the client (most likely the web browser), which encoding your site uses. This means, your browser has to guess the encoding. By default browser run in "automatic" mode, which means they will try to guess the encoding by running heuristic analyzers on the data. So, if an attacker submits UTF-7 content in certain ways, your browser thinks your site uses UTF-7 encoding. The problem comes from the fact that your htmlentities() function is told to process the data as UTF-8, so it misses the UTF-7 XSS attacks. To solve the problem, you must use the same encoding everywhere. If you use UTF-8 in your htmlentities(), you must tell the browser that UTF-8 is being used on your site. The best way is to output correct headers:

Code: Select all

header('Content-Type: text/html; charset=UTF-8');