Jordan Savant // Software Engineer

CSRF - Cross Site Request Forgery

An attacker has knowledge of an action, such as an HTTP POST to a web service, that will result in changing a users data. The attacker takes the action and places it in a location a victim would visit and engage with like clicking a link or viewing an image.

If the victim is logged into the web service, that request action will be performed against that users knowledge and can thus create serious security issues.

Example:

<form action="facebook.com?changePassword" method="post">
    <input type="hidden" name="password" value="evilpass" />
    <input type="submit" value="Click here for a new deal on Amazon!" />
</form>

Token Protection

The general way to protect against CSRF attacks is to generate a new, strongly unique token when the user session is established and store it in a user cookie or session data.

Then dynamically include that token into generated forms as a hidden input. On form submission validate that the token submitted matches the one generated. If it does not then the request came from an unapproved source.

Example token generation:

// On user login, generate a token and store in their session
$_SESSION['csrf'] = openssl_random_pseudo_bytes(16);
// On form generation include the token
<form action="/updateUser" method="post">
    <input type="hidden" name="csrf" value="<?= $_SESSION['csrf'] ?>" />
    New Password: <input type="password" name="password" />
</form>
// On form submission validate csrf
if ($_POST['csrf'] != $_SESSION['csrf']) {
    throw new \Exception("Incorrect csrf");
}
// process request if not invalid
$user->setPassword($_POST['password'];

How it protects

CSRF protection in this manner protects against mass attacks, meaning that it protects against an attacker that has generated a generic attack action that hopefully a victim uses. Because of this the CSRF token prevents that from occurring.

This protection level can be extended to generating a unique CSRF token for every request that could be made.

This would work by generataing a new token before building the form, then on form submission checking the token. Then on the next form generation using a new token. This method not only protects against CSRF attacks but also ensures that there are no duplicate form submissions.