Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

preventing csrf in php

Tags:

  1. Requiring authentication in GET and POST parameters, not only cookies;

  2. Checking the HTTP Referer header;

saw this post on wikipedia and was wondering how I can apply them

ok...I am using the Kohana PHP framework and I have the facility to determine the referrer header, but what exactly do I check in the referrer header? the framework function only returns the URL of the referrer

and how do I validate GET and POST params? against what? stored information? expected type?

like image 856
yretuta Avatar asked Nov 23 '09 01:11

yretuta


People also ask

How can CSRF attacks be prevented?

What Are CSRF Tokens. The most popular method to prevent Cross-site Request Forgery is to use a challenge token that is associated with a particular user and that is sent as a hidden value in every state-changing form in the web app.

What is CSRF attack in PHP?

It is a kind of hacking assault in which a hacker pushes you to do something against a website where you are currently signed in. Anti-CSRF implementation reduces the vulnerability of the website. With this protection, the website rejects malicious access that sends requests with no or wrong CSRF token.

How use CSRF token in Core PHP?

Summary. CSRF attacks force users to execute an action against the site where they're currently logged in. Use the bin2hex(random_bytes(35)) to generate the one-time token. Check the submitted token with the one stored in the $_SESSION to prevent the CSRF attacks.

Can we bypass CSRF token?

You can remove the CSRF token from the checking parameter and forward the request. I have seen many applications have a CSRF token enabled but they do not validate if the parameter is actually filled with the CSRF token.


1 Answers

To prevent CSRF you'll want to validate a one-time token, POST'ed and associated with the current session. Something like the following . . .

On the page where the user requests to delete a record:

confirm.php

<?php  session_start();  $token = isset($_SESSION['delete_customer_token']) ? $_SESSION['delete_customer_token'] : "";  if (!$token) {      // generate token and persist for later verification      // - in practice use openssl_random_pseudo_bytes() or similar instead of uniqid()       $token = md5(uniqid());      $_SESSION['delete_customer_token']= $token;  }  session_write_close(); ?> <html> <body> <form method="post" action="confirm_save.php">  <input type="hidden" name="token" value="<?php echo $token; ?>" /> Do you really want to delete? <input type="submit" value=" Yes " /> <input type="button" value=" No " onclick="history.go(-1);" /> </form> </body> </html> 

Then when it comes to actually deleting the record:

confirm_save.php

<?php  session_start();  // validate token  $token = isset($_SESSION['delete_customer_token']) ? $_SESSION['delete_customer_token'] : "";  if ($token && $_POST['token'] === $token) {    // delete the record    ...    // remove token after successful delete    unset($_SESSION['delete_customer_token']);  } else {    // log potential CSRF attack.  }  session_write_close(); ?> 

The token should be hard to guess, unique for each delete request, accepted via $_POST only and expire after a few minutes (expiration not shown in this example).

like image 116
leepowers Avatar answered Nov 10 '22 00:11

leepowers