Thor
Honorary Master
- Joined
- Jun 5, 2014
- Messages
- 44,236
I need some peer review if this is good enough for my login and sign up form ( Specifically referring to the CSRF Token this is simply partial code for demonstration) Got inspired by laravel, but I do not need that whole framwork for small stuff.
token_functions.php
token_request_type.php
login.php
token_functions.php
PHP:
<?php
// Generate a token for use with CSRF protection.
// Does not store the token.
function csrf_token() {
return md5(uniqid(rand(), TRUE));
}
// Generate and store CSRF token in user session.
// Requires session to have been started already.
function create_csrf_token() {
$token = csrf_token();
$_SESSION['csrf_token'] = $token;
$_SESSION['csrf_token_time'] = time();
return $token;
}
// Destroys a token by removing it from the session.
function destroy_csrf_token() {
$_SESSION['csrf_token'] = null;
$_SESSION['csrf_token_time'] = null;
return true;
}
// Return an HTML tag including the CSRF token
// for use in a form.
// Usage: echo csrf_token_tag();
function csrf_token_tag() {
$token = create_csrf_token();
return "<input type=\"hidden\" name=\"csrf_token\" value=\"".$token."\">";
}
// Returns true if user-submitted POST token is
// identical to the previously stored SESSION token.
// Returns false otherwise.
function csrf_token_is_valid() {
if(isset($_POST['csrf_token'])) {
$user_token = $_POST['csrf_token'];
$stored_token = $_SESSION['csrf_token'];
return $user_token === $stored_token;
} else {
return false;
}
}
// You can simply check the token validity and
// handle the failure yourself, or you can use
// this "stop-everything-on-failure" function.
function die_on_csrf_token_failure() {
if(!csrf_token_is_valid()) {
die("CSRF token validation failed.");
}
}
// Optional check to see if token is also recent
function csrf_token_is_recent() {
$max_elapsed = 60 * 60 * 24; // 1 day
if(isset($_SESSION['csrf_token_time'])) {
$stored_time = $_SESSION['csrf_token_time'];
return ($stored_time + $max_elapsed) >= time();
} else {
// Remove expired token
destroy_csrf_token();
return false;
}
}
?>
token_request_type.php
PHP:
<?php
// GET requests should not make changes
// Only POST requests should make changes
function request_is_get() {
return $_SERVER['REQUEST_METHOD'] === 'GET';
}
function request_is_post() {
return $_SERVER['REQUEST_METHOD'] === 'POST';
}
// Usage:
// if(request_is_post()) {
// ... process form, update database, etc.
// } else {
// ... do something safe, redirect, error page, etc.
// }
?>
login.php
PHP:
<?php
session_start();
require_once 'csrf_request_type_functions.php';
require_once 'csrf_token_functions.php';
if(request_is_post()) {
if(csrf_token_is_valid()) {
$message = "It works, good!";
if(csrf_token_is_recent()) {
$message .= " Token is recent";
} else {
$message .= " Token is NOT recent";
}
} else {
$message = "The CSRF Token is mission or mismatched.";
}
} else {
// form not submitted or was GET request
$message = "Sneaky Putin, Please login.";
}
?>
<html>
<head>
<title>Login Screen</title>
</head>
<body>
<?php echo $message; ?><br />
<form action="" method="post">
<?php echo csrf_token_tag(); ?>
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password"><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>
Last edited: