简体   繁体   中英

Check if regenerate_session_id() function actually works / Other security questions

I am building a website and i would like to secure it against Session Hijacking . Reading for this i came across someone saying that:

A general rule of thumb is to generate the session ID each time a user changes his access level.

1.When a user log in 2.When a user log out 3.When a user get administrative access

For what is worth, my website will be seperating the access levels into users logged-in and users logged-out . All forms are submitted using the POST method.

index.php

<?php
session_start();

//Setting the variable initialy to false
$_SESSION['LOGGED_IN'] = FALSE;

//to use SSL

$serverport = $_SERVER['SERVER_PORT'];

$server_http_host = $_SERVER['HTTP_HOST'];

$server_request_uri = $_SERVER['REQUEST_URI'];


if (headers_sent()) 
{
    die("HTTP headers have already been sent ");
}
else
{
if($serverport != '443')
{
ob_start();
exit(header('Location: https://'.$server_http_host.$server_request_uri));
}

}

if(isset($_POST['SUBMIT']))

{
if(isset($_POST['TOKEN']) && $_POST['TOKEN'] == $_SESSION['TOKEN'])
{
//Open database connection
require_once('connect_db.php');

//Calling functions.php that includes all custom functions
//ErrorHandler()
require_once('functions.php');        

$email = $_POST['EMAIL'];
$password = $_POST['PASSWORD'];



$statement = $DBH->prepare("SELECT * FROM user_details WHERE email=:email AND pwd=:password ");
$statement->bindParam(':email',$email);
$statement->bindParam(':password',$password);
$statement->setFetchMode(PDO::FETCH_ASSOC);
try{

$result = $statement->execute();
$rows = $statement->rowCount(); // shows how many times the user is available in the user_details table
$data = $statement->fetch(); //fetches the data related to that user from user_details table


}
catch(PDOException $e)
{
//this is custom function   
echo ErrorHandler($e);
}


if($rows == 1)
{
//this means that the user has inserted the correct credentials 
//regenerate session_id each time there is a change in the level of privilege to mitigate SESSION FIXATION  
session_regenerate_id(true);

//turning logged in variable to true as soon as it finds a match
$_SESSION['LOGGED_IN'] = TRUE;

//saves the email into a session so it can be used in mainpage.php
$_SESSION['EMAIL'] = $email;

//redirect to main page
header('Location:https://www.example.com/mainpage.php');

}
else
{
echo "<br />Wrong username or password!<br />";
}
}//closing *if(isset($_POST['TOKEN']) && $_POST['TOKEN'] == $_SESSION['TOKEN'])*
}//closing *if($_POST['SUBMIT'])*

//creating a random token to inject in our HTML form
$token = base64_encode(openssl_random_pseudo_bytes(32));

//store the random token in the session variable so we can later compare it to the one in the HTML form
$_SESSION['TOKEN'] = $token;
?>

<form action="index.php" method="POST" accept-charset="UTF-8">
<p>Email: <input type="email" name="EMAIL" /> </p>
<p><input type="hidden" name="TOKEN" value="<?php echo $token; ?>" /></p>
<p>Password <input type="password" name="PASSWORD" /> </p>
<p><input type="submit" name="SUBMIT" value="Submit" /></p>
</form>

The script accepts input email and password from the user,checks the database and if it finds a match it redirects the user to the mainpage.php.

mainpage.php

<?php
ob_start();
//the code to set the header must be called before output begins
session_start();


$serverport = $_SERVER['SERVER_PORT'];

$server_http_host = $_SERVER['HTTP_HOST'];

$server_request_uri = $_SERVER['REQUEST_URI'];

if (headers_sent())
{
die("HTTP headers have already been sent ");
}    
else
{
if($serverport != '443')
{
ob_start();
exit(header('Location: https://'.$server_http_host.$server_request_uri));
}
}



if(($_SESSION['LOGGED_IN'] == TRUE) && isset($_SESSION['LOGGED_IN']))
{
$email = $_SESSION['EMAIL'];
echo $email;

//Calling functions.php that includes all custom functions
//LogOut()
require_once('functions.php');

if(isset($_POST['LOGOUT']))
{
//its a custom function that is used for logging out    
LogOut();
}


echo '
<form method="POST" action="mainpage.php">
<p><input type="submit" name="LOGOUT" value="Log Out" /></p>
</form>

';

}
else
{
echo "Please login in order to use example.com";
}


?>

Is there a way for me to check if the way i have built these 2 scripts really regenerate the Session ID? I am using Firefox's extension LIVE HTTP headers but i am not sure if i am reading it correctly.

Also, i cannot find a way to track down and read the content of COOKIES stored while using my browser (either Chrome or Firefox or even IE11). How can i do that?

Another question that is related with security: Implementing an anti-CSRF token: Do i need to implement an anti-CSRF token for each form in my website [i guess the answer is Yes but i want to confirm it]? Should each token be different than the token used in a previous form? For example the token in index.php to be different than the token used in mainpage.php if it had a form as well.

Does the token technique prevent against any other kind of attack?

I would be glad if you indicate wrong programming in the code above, so i can correct it and learn at the same time.

Thanks!

I'm going to focus on your questions and not necessarily a thorough code review , since I think your questions are the main reason you're posting.

A simple way to check your current session id or PHPSESSID is to check under Chrome's Developer Tools > Resources > Cookies . You'll see the (initially-generated) session ID. You can check this value before and after a user logs in. If the value changes, your session id has actually been regenerated.

You can also view cookies in Firefox by right-clicking the current page, going to View Page Info and using the Cookies tab.

On CSRF (prevention) tokens, the answer varies. People use different methods to go about them. I would say a majority of websites set a token in $_SESSION upon any regenerate of the session id. So for the duration of the current session, the CSRF token will remain the same and check against hidden inputs for that CSRF token. On the other hand, I've also heard of regenerating a CSRF token for every single form that is client-facing. Your way of doing it is up to you. Nothing is 100% bulletproof, but getting as close to 100% as you can is the idea.

Take a few minutes to read up on CSRF tokens and the Synchronizer Token Pattern .

Best of luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM