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 -->
 |