Csrf Cross-Site Request Forgery
Basic concepts of csrf Cross-Site Request Forgery
It is an attack method that allows attackers to send arbitrary HTTP requests through victims. The victim referred to here is an uninformed accomplice, and all forged requests are initiated by him, not the attacker. In this way, it is difficult for you to determine which requests belong to cross-site request forgery attacks.
Attack demonstration
The following table
<formaction="buy.php"method="POST"><p> Item: <selectname="item"><optionname="pen">pen</option><optionname="pencil">pencil</option></select><br /> Quantity: <inputtype="text"name="quantity" /><br /><inputtype="submit"value="Buy" /></p></form>
Php request processing
<?php session_start(); $clean = array(); if (isset($_REQUEST['item'] && isset($_REQUEST['quantity'])) { /* Filter Input ($_REQUEST['item'], $_REQUEST['quantity']) */if (buy_item($clean['item'], $clean['quantity'])) { echo'<p>Thanks for your purchase.</p>'; } else { echo'<p>There was a problem with your order.</p>'; } } ?>
Attackers try to use the get method: http://store.example.org/buy.php? Item = pen & quantity = 1
If successful, attackers can obtain the URL format that can be purchased when a legitimate user accesses the website. In this case, Cross-Site Request Forgery is very easy, because the attacker only needs to cause the victim to access the URL.
Attackers do not need to obtain user authorization.
When a user accesses another website, if the website directs the user to initiate the above request, the browser will carry the cookie related to the user, which is equivalent to obtaining the user authorization for the illegal website.
Although there are multiple methods to initiate cross-site request forgery attacks, the method of embedding resource fragments is the most common. To understand the attack process, it is necessary to first understand how browsers request these resources.
When you access the http://www.google.com, your browser will first request the resource identified by this URL. You can view the returned content of the request by viewing the source file (HTML) of the page. After the returned content is parsed in the browser, the Google logo image is found. The image is represented by the img tag of HTML, and the src attribute of the tag represents the URL of the image. The browser then sends a request to the image. The difference between the two requests is that the URL is different.
Based on the above principle, cross-site request forgery attacks can be achieved through the img tag. Consider what will happen if you access a webpage that includes the following source code:
Because the buy. php script uses $REQUEST instead of $POST, so that every user logging on to the store.example.org store will purchase 50 pencils by requesting the URL.
The existence of Cross-Site REQUEST Forgery attack is one of the reasons why $ _ REQUEST is not recommended.
Defense methods
Use POST instead of GET to submit a form. use $
POST instead of $REQUEST
The verification form comes from the real page, not forged. Verification is required.
Generate form token
<?php session_start(); $token = md5(uniqid(rand(), TRUE)); $_SESSION['token'] = $token; $_SESSION['token_time'] = time(); ?>
When submitting the form, the token also raised the price to the server.
<formaction="buy.php"method="POST"><inputtype="hidden"name="token"value="<?php echo $token; ?>" /><p> Item: <selectname="item"><optionname="pen">pen</option><optionname="pencil">pencil</option></select><br /> Quantity: <inputtype="text"name="quantity" /><br /><inputtype="submit"value="Buy" /></p></form>
A Cross-Site Request Forgery attack must include a valid Verification code to completely mimic form submission. Because the verification code is stored in the user's session, attackers must use different verification codes for each victim. This effectively limits any attacks on a user and requires the attacker to obtain the valid Verification Code of another user. Using your own verification code to forge another user's request is invalid.
This verification code can be simply checked using a conditional expression:
<?phpif (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token']) { /* Valid Token */ } ?>
You can also add a valid time limit for the verification code, such as 5 minutes, and allow the token to be used only once:
<?php$token_age = time() - $_SESSION['token_time']; $token = $_SESSION['token']; unset($_SESSION['token']); if ($token_age <= 300) { /* Less than five minutes has passed. */ } ?>
By including the verification code in your form, you have actually eliminated the risk of cross-site request forgery. You can use this process in any form that requires an operation.
You can also allow the token to be used only once. After each request is requested, the token passes and the token is destroyed. It can be safer and prevent repeated submission of forms.
Use cookei for verification
If we ignore the fact that users' Cookies are easily stolen due to the XSS vulnerability on the website (we already know this is not uncommon, this is a good solution for CSRF. If we add random Cookies to each form request of the user, this method will become safer, but this method is not very suitable.
<?php // Hash the cookie $hash = md5($_COOKIE['cookie']); ?><formmethod="POST"action="resolve.php"><inputtype="text"name="first_name"><inputtype="text"name="last_name"><inputtype="hidden"name="check"value="<?=$hash;?>"><inputtype="submit"name="submit"value="Submit"></form><?php // Check if the "check" var exists if(isset($_POST['check'])) { $hash = md5($_COOKIE['cookie']); // Check if the values coincide if($_POST['check'] == $hash) { do_something(); } else { echo "Malicious Request!"$$ } } else { echo "Malicious Request!"$$ } ?>
The idea of this solution is: every time a user submits a request, the user needs to fill in a random string on the image in the form .... this solution can completely solve CSRF, but I personally think it is not very easy to use.