PHP Form Token Usage and Handling

PHP form token usage and handling

There is no need to do what you are attempting. When you start a session in PHP with session_start() a unique SESSIONID is already generated for you. You should not be putting this on the form. It is handled via cookies by default. There is also no need to check the SESSIONID either, that again is handled for you.

You are responsible for authenticating the user and storing their authenticated identity (e.g. $_SESSION['user_id'] = $userId in the SESSION. If a user logs out you destroy their session with session_destroy.

You should ensure session_start() is one of the first things for all pages in your site.

Here is a basic example:

<?php
session_start(); // starts new or resumes existing session
session_regenerate_id(true); // regenerates SESSIONID to prevent hijacking

function login($username, $password)
{
$user = new User();
if ($user->login($username, $password)) {
$_SESSION['user_id'] = $user->getId();
return true;
}
return false;
}

function logout()
{
session_destroy();
}

function isLoggedIn()
{
return isset($_SESSION['user_id']);
}

function generateFormHash($salt)
{
$hash = md5(mt_rand(1,1000000) . $salt);
$_SESSION['csrf_hash'] = $hash
return $hash;
}

function isValidFormHash($hash)
{
return $_SESSION['csrf_hash'] === $hash;
}

Edit: I misunderstood the original question. I added the relevant methods above for generating and validating form hashes;

Please see the following resources:

  • PHP Session Handling
  • session_start()
  • session_destroy()

How can I pass a token generated on one PHP form to a form that processes it?

  1. Generate and save token in server side (sql or others..)
  2. Create cookie with the token (client side)
  3. When the form is submit, retrieve the token from cookie
  4. if the cookie is the same than the saved token, thats ok

Generate token:

$formName = "signin"; // name of the form 
$ip = get_ip(); // create a function to get the ip of the user
$salt = "8077_(-(àyhvboyr(à"; // uniq secret salt
$token = md5(sha1($salt.$ip).sha1($salt.$formName));
...

if(empty($_COOKIE['token'])){ // if(empty($_SESSION['token'])){

setcookie("token",$token, time()+3600*1); // use with cookie // time()+3600*1 = now + 1 hour
$_SESSION['token'] = $token; // OR use with session

}else{

// when the form is submit regenerate the token and compare with the request token
if($_COOKIE['token'] == $token){ // OR if($_SESSION['token'] == $token){
// request from server - ok
// ...
}else{
// bad request
setcookie("token",0); // destruct cookie
$_SESSION['token'] = ""; // OR destruct session
// redirect at the first form
}
}

<form>
// if you want use the token directly in your form, add this :
<input type="hidden" name="token" value="<?php echo $token ?>" />
</form>

PHP Tokens for Forms and Authentication

Authentification mechanism creates a token when form displayed, and was stored it on server side.
Also auth mechanism adds token as hidden input to form. When you send it, auth system check is it in server-side storage.
If token found, authentification process will continue and token was removing.

It protects from spamming form action script.

Example using with logout url:

<?php 
// Generate token
$logout_token = md5(microtime().random(100, 999));
session_start();
// Store token in session
if (!is_array($_SESSION['logout_tokens']) {
$_SESSION['logout_tokens'] = array();
}
$_SESSION['logout_tokens'][] = $logout_token;
?>
<a href="/logout/?logout_token=<?= $logout_token ?>">logout</a>

Script, that processing logout:

<?php
$done = false;
if (!empty($_GET['logout_token'])) {
// Get token from url
$logout_token = $_GET['logout_token'];
session_start();
if (!is_array($_SESSION['logout_tokens']) {
$_SESSION['logout_tokens'] = array();
}
// Search get token in session (server-side storage)
if (($key = array_search($logout_token, $_SESSION['logout_tokens'], true)) !== false) {
// Remove used token from storage
unset($_SESSION['logout_tokens'][$key]);
// Do logout
$done = true;
}
}
if ($done === false) {
echo "Something went wrong.";
}

Form action and antiCSRF token

Generally speaking, neither registration nor login forms need CSRF protection. Neither of them do anything with the logged-in user's personal data or authority. That said, there is no real reason to not have CSRF protection as you can write a generic system and apply it to every form on the site (unless you explicitly don't want CSRF protection, such as for search forms).

In order to prevent possible CSRF attacks i need to "save" the generated hash in a SESSION variable {$_SESSION['hashed_token'] = $_POST['hashed_token']}and then compare it to the value of the hash in the hidden form input field,

This is all sensible

after we redirect to main.php.

Don't do that. Put the code to do the comparison in a general function. Include it on all the form processing pages and run it when you process the form.



Related Topics



Leave a reply



Submit