Analysis of CSRF and XSS
preface
Bloggers recently had an interview and encountered a question: * * What are the principles of CSRF and XSS? How to prevent CSRF and XSS** Because the blogger didn't understand this part deeply enough, the answer in the interview was not comprehensive enough. Today, let's discuss the mystery behind CSRF and XSS!
This part of the knowledge points in the interview mainly focus on the authentication and authorization (cookie, session and token) in the project, or do you want to focus on mastering cookies, session and token before learning CSRF (key) and XSS!
1. Background
With the rapid development of the Internet, information security has become one of the most concerned focuses of enterprises, and the front end is a high-risk stronghold causing enterprise security problems. In the era of mobile Internet, in addition to the traditional security problems such as XSS and CSRF, front-end personnel often encounter new security problems such as network hijacking and illegal call of Hybrid API. Of course, the browser itself is also evolving and developing, and new technologies such as CSP and same site cookies are constantly introduced to enhance security, but there are still many potential threats, which requires front-end technicians to constantly "check for leaks and make up for deficiencies".
2. Introduction to CSRF
CSRF is a cross domain Request Forgery: the attacker induces the victim to enter a third-party website and sends a cross site request to the attacked website in the third-party website. Use the registration certificate obtained by the victim in the attacked website to bypass the background user authentication, so as to impersonate the user to perform an operation on the attacked website.
The concept of "cross domain" is often asked in the interview. Cross domain means that the browser cannot execute scripts of other websites! It is caused by the homology policy of the browser and the security restriction imposed by the browser on javascript.
For example, if a page wants to obtain b page resources, if the protocol, domain name, port and sub domain name of a and b pages are different, the access actions are cross domain, and the browser generally restricts cross domain access for security issues, that is, cross domain requests for resources are not allowed. Note: cross domain access restrictions are actually browser restrictions. It's important to understand this!!!
In order to facilitate your understanding, give an example to explain:
Example 1:
1. Now there is A bank website A, which completes the bank transfer operation with GET request, such as: http://www.mybank.com/Transfer.php?toBankId=11&money=1000
2. There is also a website B, in which there is an HTML code as follows:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
3. First, you log in to the bank website A and then visit the dangerous website B. Oh, at this time, you will find that your bank account is less than 1000 yuan. What about the money? Where's the money? I believe you must be curious! Let's explore why this is the case?
Reason: bank A violated the HTTP specification and used get request to update resources. Before visiting the dangerous website B, you have logged in to the bank website A, and the third party in B requests the third-party resources in the way of get (the third party here refers to the bank website, which was originally A legal request, but it was used by criminals). Therefore, your browser will bring the Cookie of your bank website A and send A get request to obtain the resources“ http://www.mybank.com/Transfer.php?toBankId=11&money=1000 ”As A result, after receiving the request, the bank website server thought it was an update resource operation (transfer operation), so it immediately carried out the transfer operation
Example 2:
In order to eliminate the above problems, the bank decided to use POST request to complete the transfer operation. The WEB form of bank website A is as follows:
<form action="Transfer.php" method="POST"> <p>ToBankId: <input type="text" name="toBankId" /></p> <p>Money: <input type="text" name="money" /></p> <p><input type="submit" value="Transfer" /></p> </form>
Background processing page transfer PHP is as follows:
<?php session_start(); if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money'])) { buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']); } ?>
Website B still contains that HTML code:
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
Like the operation in example 1, you first log in to the bank website A and then visit the dangerous website B. as A result... Like example 1, you lose 1000 ~ t again_ T. The reason for the accident is that the bank used it in the back office R E Q U E S T go Obtain take please seek of number according to , and _ REQUEST to get the requested data, and R # REQUEST to obtain the requested data, and_ REQUEST can obtain both GET REQUEST data and POST REQUEST data, which makes the background handler unable to distinguish whether it is GET REQUEST data or POST REQUEST data. In PHP, you can use G E T and _ GET and G. ET and_ POST obtains the data of GET request and POST request respectively. In JAVA, like the request used to obtain request data, there is a problem that GET request data and POST data cannot be distinguished
Example 3:
This time, bank A learned from the experience of the previous two times and decided to change the method of obtaining the requested data to$_ POST, only get the data requested by POST, and process the page transfer in the background The PHP code is as follows:
<?php session_start(); if (isset($_POST['toBankId'] && isset($_POST['money'])) { buy_stocks($_POST['toBankId'], $_POST['money']); } ?>
However, website B is not willing to give up. It changes the code to:
<html> <head> <script type="text/javascript"> function steal() { iframe = document.frames["steal"]; iframe.document.Submit("transfer"); } </script> </head> <body onload="steal()"> <iframe name="steal" display="none"> <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php"> <input type="hidden" name="toBankId" value="11"> <input type="hidden" name="money" value="1000"> </form> </iframe> </body> </html>
Unfortunately, if the bank does not send the request to the above block again, it will still be dangerous for the user to continue to POST here!
To sum up the above three examples, the main attack modes of CSRF are basically the above three, of which the first and second are the most serious. Because the trigger conditions are very simple, one can be used, while the third is more troublesome and requires JavaScript, so the use opportunities will be much less than the previous ones. However, in any case, as long as the CSRF attack is triggered, The consequences can be serious.
From the above three attack modes, we can see that CSRF attack is an implicit authentication mechanism from the WEB! Although the authentication mechanism of WEB can ensure that a request comes from a user's browser, it can not guarantee that the request is sent with the approval of the user!
3. Coping strategies of CSRF
The defense of CSRF can start from the server and client. The defense effect is to start from the server. The effect is better. Now the general CSRF defense is also carried out on the server.
3.1. The server performs CSRF defense
There are many CSRF methods on the server side, but the general idea is the same, that is, adding pseudo-random numbers on the client page.
3.1.1. Cookie hashing (all forms contain the same pseudo-random value):
This may be the simplest solution, because the attacker cannot obtain the third-party cookie (theoretically), so the data in the form fails to be constructed:
<?php //Construct encrypted Cookie information $value = "DefenseSCRF"; setcookie("cookie", $value, time()+3600); ?>
Then add the Hash value to the form to verify that this is indeed the request sent by the user.
<?php $hash = md5($_COOKIE['cookie']); ?> <form method="POST" action="transfer.php"> <input type="text" name="toBankId"> <input type="text" name="money"> <input type="hidden" name="hash" value="<?=$hash;?>"> <input type="submit" name="submit" value="Submit"> </form>
Then verify the hash value on the server:
<?php if(isset($_POST['check'])) { $hash = md5($_COOKIE['cookie']); if($_POST['check'] == $hash) { doJob(); } else { //... } } else { //... } ?>
This method can eliminate 99% of CSRF attacks, and there is still 1% of them... Because the user's cookies are easy to be stolen due to the XSS vulnerability of the website, this is the other 1%. General attackers will give up when they see the need to calculate the Hash value, except for some. Therefore, this is not the best method if 100% elimination is required.
3.1.2 verification code
The idea of this scheme is: each user submission requires the user to fill in a random string on the picture in the form. This scheme can completely solve CSRF, but it doesn't seem to be very good in ease of use.
3.1.3. One time tokens (different forms contain a different pseudo-random value)
One thing to note when implementing one time tokens is "compatibility of parallel sessions". If a user opens two different forms at the same time on a site, CSRF protection measures should not affect his submission of any form. Consider what happens if the site generates a pseudo-random value to overwrite the previous pseudo-random value every time the form is loaded: the user can only successfully submit the last form he opened because all other forms contain illegal pseudo-random values. Care must be taken to ensure that CSRF protection does not affect tabbed browsing or browsing a site using multiple browser windows.
For example:
1. Write a token generation function (gen_token()):
<?php function gen_token() { //I'm greedy for convenience here. In fact, it's not safe to use the random number obtained by Rand() as a token alone. //For this, please refer to Random object created and used only once in my Findbugs notes $token = md5(uniqid(rand(), true)); return $token; }
2. Write the Session token generation function (gen_stoken()):
<?php function gen_stoken() { $pToken = ""; if($_SESSION[STOKEN_NAME] == $pToken){ //No value, assign a new value $_SESSION[STOKEN_NAME] = gen_token(); } else{ //Continue using old values } } ?>
3. Functions for generating hidden input fields from WEB forms:
<?php function gen_input() { gen_stoken(); echo "<input type=\"hidden\" name=\"" . FTOKEN_NAME . "\" value=\"" . $_SESSION[STOKEN_NAME] . "\"> "; } ?>
4. WEB form structure:
<?php session_start(); include("functions.php"); ?> <form method="POST" action="transfer.php"> <input type="text" name="toBankId"> <input type="text" name="money"> <? gen_input(); ?> <input type="submit" name="submit" value="Submit"> </FORM>
5. The server checks the token
4. Introduction to XSS
XSS attack usually refers to injecting malicious instruction code into the web page through ingenious methods by taking advantage of the loopholes left during web page development, so that the user can load and execute the web page program maliciously created by the attacker. These malicious web programs are usually JavaScript, but they can actually include Java, VBScript, ActiveX, Flash or even ordinary HTML. After a successful attack, the attacker may get higher privileges (such as performing some operations), private web page content, sessions, cookie s and other contents.
5. Countermeasures of XSS
5.1. Front end rendering separates code and data
In the front-end rendering, we will clearly tell the browser whether the content to be set below is text (. innerText), attribute (. setAttribute), style (. Style), etc. Browsers will not be easily deceived into executing unexpected code.
Javascript: try not to use innerHTML where textContent or innerText can be used;
query: where text() can be used, try not to use html();
5.2. Escape HTML when splicing it
If it is necessary to splice HTML, it is necessary to use an appropriate escape library to fully escape the insertion points of HTML template. Common template engines, such as dot JS, ejs, FreeMarker, etc. there is usually only one rule for HTML escape, that is to escape the characters & < > "/ which can indeed play a certain role in XSS protection, but it is not perfect. Here we recommend a plug-in for front-end XSS attack prevention: JS XSS, Git 3.8K Star and 60W weekly downloads have proved its strength.
Of course, there are other strategies, which will not be repeated here. If you are interested, you can refer to the relevant information!
reference:
1,On CSRF attack mode - hyddd - blog Garden (cnblogs.com)
2,(12 messages) this time, fully understand the XSS attack_ TZ CSDN blog
3,Cross site scripting attack_ Baidu Encyclopedia (baidu.com)
4,Cross Site Request Forgery_ Baidu Encyclopedia (baidu.com)