52 lines
3.1 KiB
Markdown
52 lines
3.1 KiB
Markdown
---
|
|
title: Cross Site Request Forgery
|
|
---
|
|
## Cross Site Request Forgery
|
|
|
|
Cross Site Request Forgery is a vulnerability in the application caused by the programmer not checking where a request was sent from - this attack is sent to a high privilege level user to gain higher level access to the application.
|
|
|
|
### Example Cross Site Request Forgery Attack
|
|
An online blog allows users to submit comments and include an image in the comment, the blog's admin panel allows the blog's author to delete a comment by loading the URL `/admin/deletecomment.php?id=123`. A malicious user could make an image tag that loads the delete comment url for example `<img src="/admin/deletecomment.php?id=123" />` so next time an admin views the comment, the admin's computer will load the url and delete comment number 123.
|
|
|
|
### Defending your website from cross site request forgery attacks in PHP
|
|
To defend against a cross site request forgery attack, you should check against a regularly changed token. The url `/admin/deletecomment.php?id=123` would change to `/admin/deletecomment.php?id=123&csrf-token=random-per-user-unique-string-here`.
|
|
|
|
```PHP
|
|
<?php
|
|
// Checking a request's CSRF Token (if true the comment is deleted, if false the comment remains.)
|
|
session_start();
|
|
if ($_GET['csrf-token'] == $_SESSION['csrf-token']){
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
```
|
|
|
|
**Tips:**
|
|
* Keep a CSRF Token completely random and change per session (the openssl functions can help with this)
|
|
* PHP sessions are useful for storing a CSRF Token accessible to both the user and the server, you could also make this process database driven if you are so inclined.
|
|
* Change the CSRF Token on a session every 24 hours. On a high risk application you might want to change it upon every successful request however that will cause issues with users using multiple tabs.
|
|
|
|
#### Securely generating a Token
|
|
When setting a CSRF Token it is important that it is impossible to guess the key. The OpenSSL functions in PHP can generate a randomized key for you and store as a session variable.
|
|
|
|
```PHP
|
|
<?php
|
|
session_start();
|
|
$_SESSION['csrf-token'] = bin2hex(openssl_random_pseudo_bytes(16));
|
|
```
|
|
|
|
#### Using a CSRF Token to complete legitimate requests
|
|
You can include the session variable you saved earlier with your CSRF token in the URL make sure a legitimate administrator is allowed to delete comments. Without the correct token the request will be blocked.
|
|
|
|
```PHP
|
|
<?php
|
|
session_start();
|
|
echo '<a href="/admin/?id=123&csrf-token='.$_SESSION['csrf-token'].'">Delete Comment</a>'; // Only the logged in user has access to the CSRF Token - the token isn't accessible to the attacker preventing their attack from being successful.
|
|
```
|
|
|
|
#### More Information:
|
|
* <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)" rel="nofollow">OWASP Wiki - Cross Site Request Forgery</a>
|
|
* <a href="https://secure.php.net/manual/en/function.bin2hex.php">php.net bin2hex() manual</a>
|
|
* <a href="https://secure.php.net/manual/en/function.openssl-random-pseudo-bytes.php">php.net openssl_random_pseudo_bytes() manual</a> <!-- I used html special entities here due to issues displaying the underscore characters -->
|