CSRF vulnerability
1. Principle
csrf (cross-site request forgery): cross-site request forgery
CSRF attacks use the website's trust in the user's browser. The attacker hijacks the user's login information, sends some unintentional requests to the website, and performs some operations.
In a CSRF attack, the attacker compromises session integrity by controlling the user's browser to send malicious additional requests
Why can an attacker take control of a user's browser?
According to the browser's security policy, the current page is allowed to send requests to any address. Therefore, when the user clicks the attacker's malicious link on the trusted website, he enters the page constructed by the attacker. This page is not protected. User-controlled, so the attacker can control the user's browser to send requests by controlling the pages constructed by himself.
Requirements to generate a CSRF attack:
1. The user has logged in to the website and can perform normal operations on the website
2. The user clicks on the attacker’s URL link
2. csrf utilization
Environment: phpstudy+DVWA
1.low level
Change DVWA security to low
low level core code
<?php
//核心代码
if( isset( $_GET[ 'Change' ] ) ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ]; //核心代码
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
It can be seen that the low level only needs to be consistent with password_new and password_conf
For example, we want to change the password to 777
1. Method 1: It can be modified directly in the url, because the modification password at this time is not protected in any way
2. Method 2: Or write an HTML file and name it localhost.html (this file should be placed under the www folder 1)
<!DOCTYPE HTML>
<html>
<head></head>
<title></title>
<body>
<img src="http://localhost/DVWA-master/vulnerabilities/csrf/?password_new=777&password_conf=777&Change=Change#"/>
<h1> 404</h1>
<h2>not found</h2>
</body>
</html>
We open this localhost.html file in the browser
Well, at this time we have also completed the password modification
2.medium level
We first modify the level of dvwa security to medium
Core code:
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Checks to see where the request came from
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
//上一行为增加的代码
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
It can be seen that the medium level has one more stripos than the low level ( SERVER [ ′ HTTPREFERER ′ ] , _SERVER[ 'HTTP_REFERER' ] ,SERVER[′HTTPREFERER′ ],_SERVER[ 'SERVER_NAME' ]) !== false condition
It means that it is necessary to verify whether the referer contains the server_name parameter (the host in the http request and the host name to be accessed). The filtering rules indicate that the referer must contain the host name. Here is localhost, so we can use localhost.html to bypass pass
We open burpsuite and open the proxy module
We continue to return to the browser, enter newpassword=777, confirm new password=777, and click the change button
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-KVp5Osp5-1654518743200) (C:\Users\zhs\AppData\Roaming\Typora\typora-user-images\ image-20220606184545305.png)]
Well, this time we caught the bag
Then, we send it to the repeater module
We modify the referer in the repeater, the original referer is Referer: http://localhost/DVWA-master/vulnerabilities/csrf/
change into
http://localhost/localhost.html
Send it out (click the send button)
Seeing that the response responds with a 200 OK means that the modification is successful
3.high level
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
//上一行为新增核心代码
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
It can be seen that the high level has one more line of code checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
If the attacker wants to modify the user's password, he must obtain the token value (when the user visits the password modification page, the server will return a token value, and then the user must bring the token value when sending a password modification request to the browser, only the token value correct, the server will proceed to the next operation)
Since browser cross-domain requests are not allowed, we will not perform high-level exercises here
4. Impossible level
This level must know the initial password, if the attacker does not know, there is no way to attack
3. csrf defense
1. Verification code
2.refer
referer is included in the http request: the meaning of referer is to indicate the source of a request
When users on some websites perform sensitive operations, we can set referer. If it does not come from the same url source, we directly reject the request
3. Add token value and verify
The essence of a successful csrf attack is that the attacker can guess all important parameters of the user, and token solves this problem
The token value is a unique value generated by the server for each user, it is not placed in the cookie, so it will not be used by attackers
When the user wants to send a request, the token value must be brought
If the attacker's request does not contain a token value, this request will be rejected by the server.