In a code i have seen this creation of token for a login page:
$token = $_SESSION['token'] = md5(uniqid(mt_rand(),true));
Then this token is echoed as a hidden input in the login form and on submitted, php code to validate login also checks this token like:
public function isTokenValid()
{
return (!isset($_SESSION['token']) || $this->_token != $_SESSION['token'])? 0 : 1;
}
What is the use of this token ?
Edit: This page is describes the use of it: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
These input fields need to be validated, which ensures that the user has entered information in all the required fields and also validates that the information provided by the user is valid and correct.
In HTML, certain attribute can only be assigned values known as name tokens. Name tokens are ASCII character strings composed of the letters a-z or A-Z, the digits (0-9), dashes (-) and periods (.), but nothing else. In addition, a name token must begin with a letter.
The $_SERVER["PHP_SELF"] is a super global variable that returns the filename of the currently executing script. So, the $_SERVER["PHP_SELF"] sends the submitted form data to the page itself, instead of jumping to a different page. This way, the user will get error messages on the same page as the form.
Mainly there are two ways to perform HTML form validation. The first is using the built-in functionality provided in HTML5, and the second is by using JavaScript. Using the first method, we don't need to write extra code.
Approach like this is commonly used to prevent CSRF vulnerabilities
This is used to guard against cross-site request forgery attacks, whereby a non-authorized user can force a currently logged-in (authorized) user to execute requests on your website by crafting links resulting in form posts.
The idea is that your site must first have generated the anti-CSRF token and passed it to the authorized client. But that token is unknown to the attacker and must be used to complete a valid request back to your website.
An example CSRF attack might be enticing a user to click a link, which results in a spam post being posted to the user's Facebook stream, if Facebook had not properly protected against CSRF with a token. Because the user was already logged in, the attacked site (Facebook) treated the posting request as valid.
Tokens are useful to provide some level of protection from CSRF attacks, and they are also useful for enforcing a limit on submissions of a form.
Or put simply, can be used to prevent someone from unintentionally submitting the same form twice by clicking the submit button twice.
Example: You are making an online transfer on your bank's website of $10 from account A to account B. When the "transfer funds" screen comes up, in the background is a unique token. You enter the to/from accounts and the amount and press the submit button, and then press it again by accident before the next page loads.
Your browser sends the HTTP POST twice. For the first request, the server receives the token, confirms that it's valid, then deletes or marks it as invalid. For the second request, the server finds that the (same) token is no longer valid and does not process the transfer. Had it not done so, you would have just transferred $20 instead of $10.
One way to think about it is when you load a form you get a token specially for that instance of the form you just loaded. If you want to submit, use the token. Once you use the token it's gone. Want another token? Reload the page/form to get another one.
Note: there are ways to use JavaScript to prevent duplicate button clicks, which should also be used, but this doesn't help if there is a duplicate HTTP request for some other reason (browser bug, hardware issue, etc.). Tokens should be used for any transaction that results in data changing or use of resources (like printing) and should not be duplicated unintentionally.
You should put a token in your html form in order to protect your web site from CSRF attacks.
CSRF Attack Explanation - Practical example:
CSRF Attacks are known as kind of attacks the the attacker exploits the reliability and validity of a valid authenticated user, Here is an example of it:
Example: You have a button and textbox on your html form that allows the users to post their comments by clicking on it, it looks like follows:
<?php
// www.mydomain.com/comment.php
session_start();
if (isset($_POST['send']) {
$comment = $_POST['comment'];
// + ... + publish the comment ...
// + more server side logic here
}
?>
<html>
<body>
<form>
<input type="text" name="comment"/>
<button name="send">Send</button>
</form>
</body>
</html>
A CSRF attacker can create the following web page:
<html>
<body>
<form method="post" action="www.mydomain.com/comment.php">
<input type="hidden" name="comment" value="The attacker comment"/>
<button name="send">Comment for www.mydomain.com</button>
</form>
</body>
</html>
The attacker put on the web page the same controls that the original web page has, and with the same names, this page can be hosted on different domain.
Now the attacker publish this page on the web and users that are signed in to their accounts on 'www.mydomain.com' can just visit this page and click on the button, and once this is done - the attacker's comment is posted from the victim's account, nothing strange happened because the server accepts this comment since the request came from the authenticated user.
Solution
In order to protect your web site from CSRF attacks you need to identify on your server which from made the request.
You can put a unique key on your form and save it on the server (session) after the user logs in to your web site, and use this key as the identifier of this form, on each post validate the key in the submitted form with the key saved in the session.
In the above example, a valid page should look like:
<?php
// www.mydomain.com/comment.php
session_start();
if (isset($_POST['send']) {
if (isset($_POST['CSRF']) && $_POST['CSRF'] == $_SESSION['CSRF']) {
$comment = $_POST['comment'];
// + ... + publish the comment ...
// + more server side logic here
}
else {
echo '404 Not found!'; // possible csrf atack.
exit();
}
}
$csrf = bin2hex(random_bytes(32));
$_SESSION['CSRF'] = $csrf;
?>
<html>
<body>
<form>
<input type="text" name="comment"/>
<button name="send">Send</button>
<input type="hidden" name="csrf" value="<?php echo $csrf; ?>"/>
</form>
</body>
</html>
Now, This web page is protected against CSRF, the attacker's form doesn't contain the csrf key so the server will reject it as for all forms without a valid CSRF key, and it will be imposiible for an attacker to get a valid CSRF key since the key is randomly generated and expires with the session.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With