How to deal with csrf attacks

Source: Internet
Author: User
Tags csrf attack

Introduction:Cross Site Request Forgery (Cross-Site Request Forgery) is a type of network attack, the attack can send a request in the name of the victim to the attacked site without the victim's knowledge, so that the operation under the permission protection is performed without authorization, it is harmful. However, this attack method is not well known and many websites have csrf security vulnerabilities. This article first introduces the basic principles and dangers of csrf, and then analyzes several common defense methods to compare their advantages and disadvantages. Finally, this article will show you how to defend against csrf attacks on your website and share some best practices during development.

 

Csrf background and introduction

Cross Site Request Forgery (Cross-Site Request Forgery) is a type of network attack. It was listed as one of the top 20 security risks on the Internet in 2007. Other security risks, such as SQL Script Injection and cross-site scripting (XSS) attacks, have become increasingly common in recent years. Many websites have also defended against them. However, for most people, csrf is still a strange concept. Even the well-known Gmail, there was a csrf vulnerability by the end of 2007, which caused huge losses to Gmail users by hacking.

Csrf attack instance

A csrf attack can send a request in the name of the victim to the attacked site without the victim's knowledge, so that the operation under permission protection can be performed without authorization. For example, the victim Bob has a deposit in the bank and sends a request to the Bank's website for http://bank.example/withdraw? Account = Bob & amount = 1000000 & for = bob2 enables Bob to transfer a deposit of 1000000 to the account of bob2. Generally, after a request is sent to a website, the server first verifies whether the request comes from a valid session and Bob, the user of the session, has successfully logged in. The hacker Mallory also has an account in the bank. He knows that the above URL can transfer money. Mallory can send a request to the bank by itself: http://bank.example/withdraw? Account = Bob & amount = 1000000 & for = Mallory. However, this request comes from Mallory rather than Bob and cannot pass security authentication. Therefore, this request does not work. At this time, Mallory thought of using csrf attack method, he first made a website, put the following code in the Website: src = "http://bank.example/withdraw? Account = Bob & amount = 1000000 & for = Mallory ", and induces Bob to access his website through advertisements. When Bob accesses the website, the above URL will be sent to the bank from Bob's browser, and the request will be sent together with the cookie in Bob's browser to the bank server. In most cases, this request fails because it requires Bob's authentication information. However, if Bob happens to have just visited his bank, the session between his browser and the bank website has not expired, and the browser cookie contains Bob's authentication information. At this time, the tragedy happened, And the URL request will be responded, and money will be transferred from Bob's account to Mallory's account, while Bob did not know at the time. Later, Bob finds that his account has less money. Even if he goes to the bank to query logs, he can only find that one of his legitimate requests has actually transferred funds without any traces of attacks. Mallory can get the money and get free.

Csrf attack object

Before discussing how to defend against csrf attacks, we must first clarify the objects of csrf attacks, that is, the objects to be protected. From the above example, we can see that csrf attacks are used by hackers to obtain the trust of the server by using the cookie of the victim. However, hackers cannot obtain the cookie or see the content of the cookie. In addition, hackers cannot parse the results returned by the server due to browser same-origin policy restrictions. Therefore, a hacker cannot get anything from the returned results. All he can do is send a request to the server to execute the command described in the request and directly change the data value on the server side, instead of stealing data from the server. Therefore, we need to protect services that can directly generate data changes. for services that read data, csrf protection is not required. For example, the transfer request in the banking system will directly change the account amount and be attacked by csrf, which requires protection. While querying the balance is a read operation on the amount and does not change the data, the csrf attack cannot parse the results returned by the server and does not require protection.

 

Current policies for csrf defense

Currently, there are three main policies for csrf protection in the industry: verifying the HTTP Referer field, adding token to the request address, and verifying; customizing attributes in the HTTP header and verifying. The three policies are described in detail below.

Verify the HTTP Referer Field

According to the HTTP protocol, a field in the HTTP header is called Referer, which records the source address of the HTTP request. In general, the request to access a secure restricted page comes from the same website, such as the need to access the http://bank.example/withdraw? Account = Bob & amount = 1000000 & for = Mallory. You must first log on to bank. Example and then click the button on the page to trigger the transfer event. At this time, the Referer value of the transfer request will be the URL of the page where the transfer button is located, usually the address starting with the bank. Example domain name. If a hacker wants to launch a csrf attack on a bank website, he can only construct a request on his own website. When a user sends a request to a bank through a hacker's website, the Referer of the request points to the hacker's own website. Therefore, to defend against csrf attacks, a bank website only needs to verify its Referer value for each transfer request. the domain name starting with example indicates that the request is from the bank website and is legal. If the Referer is another website, it may be a hacker's csrf attack and the request is rejected.

The obvious advantage of this method is that it is simple and easy, and common website developers do not need to worry about csrf vulnerabilities, you only need to add an interceptor to all security-sensitive requests at the end to check the Referer value. Especially for existing systems, there is no need to change any existing code and logic of the current system, and there is no risk and it is very convenient.

However, this method is not foolproof. The Referer value is provided by the browser. Although there are clear requirements on the HTTP protocol, the specific implementation of Referer in each browser may be different, and there is no security vulnerability in the browser itself. By verifying the Referer value, security is guaranteed by a third party (that is, a browser). Theoretically, This is not safe. In fact, for some browsers, such as IE6 or ff2, there are already some ways to tamper with the Referer value. If the bank. Example website supports Internet Explorer 6, hackers can set the Referer value of the user's browser to the address starting with the bank. Example domain name, so that they can pass the verification and initiate csrf attacks.

Hackers cannot tamper with the Referer value even if they use the latest browser. Because the Referer value records the user's access source, some users think this will infringe on their own privacy, in particular, some organizations worry that the Referer value may expose some information in the Intranet to the Internet. Therefore, the user can set a browser so that the user does not provide Referer when sending the request. When they access a bank website normally, the website will be considered as a csrf attack because the request does not have a referer value, and the access of legal users is denied.

Add and verify the token in the request address

The reason why csrf attacks are successful is that hackers can completely forge user requests and all user authentication information in this request is stored in cookies, therefore, hackers can directly use their cookies to pass security verification without knowing the authentication information. To defend against csrf, the key lies in placing information that cannot be forged by hackers in the request, and the information does not exist in cookies. You can add a random token in the form of parameters in the HTTP request, and create an interceptor on the server to verify the token. If there is no token in the request or the token content is incorrect, the request may be rejected due to a csrf attack.

This method is safer than checking the referer. the token can be generated and put in the session after the user logs in, and then the token is taken out of the session during each request, compared with the token in the request, the difficulty of this method is how to add the token as a parameter to the request. For a GET request, the token is attached to the request address, so that the URL becomes http: // URL? Csrftoken = tokenvalue. For post requests, <input type = "hidden" name = "csrftoken" value = "tokenvalue"/> must be added at the end of form, in this way, the token is added to the request as a parameter. However, in a website, there are many places where requests can be accepted. It is very troublesome to add tokens for each request and it is easy to miss out, the common method is to use JavaScript to traverse the entire DOM tree every time a page is loaded, and add token to all the and form labels in the Dom. In this way, most requests can be solved, but this method does not work for HTML code dynamically generated after the page is loaded. You also need to manually add token during coding.

Another disadvantage of this method is that it is difficult to ensure the security of the token itself. In particular, in some forums and other websites that support content published by users, hackers can publish their own personal website addresses. Because the system will also add a token to the address, hackers can get this token on their own websites and immediately launch csrf attacks. To avoid this, the system can add a judgment when adding a token. If the link is linked to your own site, add a token later. If it is directed to the Internet, it will not be added. However, even if the csrftoken is not attached to the request as a parameter, the hacker's website can also obtain the token value through Referer to launch a csrf attack. This is why some users prefer to manually disable the browser Referer function.

Customize attributes in the HTTP header and verify the attributes

This method also uses token for verification. Unlike the previous method, token is not placed in the HTTP request in the form of parameters, instead, it is placed in the Custom Attributes of the HTTP header. Through the XMLHttpRequest class, you can add the HTTP header attribute csrftoken to all requests of this class at a time and put the token value into it. This solves the inconvenience caused by adding token to the previous request. At the same time, the address requested through XMLHttpRequest is not recorded in the address bar of the browser, do not worry that the token will be leaked to other websites through referer.

However, this method has many limitations. XMLHttpRequest requests are usually used for asynchronous page refreshing in Ajax methods. Not all requests can be initiated using this class, and the pages obtained through such requests cannot be recorded by the browser, this will cause inconvenience to users by moving forward, backward, refresh, and adding to favorites. In addition, for legacy systems that do not have csrf protection, you need to use this method to protect them. Instead, you need to change all requests to XMLHttpRequest requests. In this way, you almost need to rewrite the entire website, this price is undoubtedly unacceptable.

 

Java sample code

The following uses Java as an example to illustrate the above three methods with code. No matter what method is used, the interceptor on the server is necessary. It will check whether the incoming request meets the requirements and decide whether to continue or discard the request based on the results. In Java, the interceptor is implemented by the filter. We can write a filter and configure it in Web. XML to block requests to access all resources that require csrf protection.

The Referer verification code for the request in the filter is as follows:


Listing 1. Verifying Referer in Filter

// Obtain the Referer value string Referer = request. getheader ("Referer") from the HTTP header; // determine whether the Referer starts with bank. Example If (Referer! = NULL) & (referer. trim (). startswith ("bank. example ") {chain. dofilter (request, response);} else {request. getrequestdispatcher ("error. JSP "). forward (request, response );}

 

The above code first obtains the Referer value and then judges it. When it is not empty, it uses the bank. if it starts with example, the request will continue. Otherwise, it may be a csrf attack and it will go to error. JSP page.

If you want to further verify the token value in the request, the Code is as follows:


Listing 2. Verifying the token in the filter request

Httpservletrequest Req = (httpservletrequest) request; httpsession S = req. getsession (); // obtain the csrftoken attribute string token en = (string) s from the session. getattribute ("csrftoken"); If (token en = NULL) {// generate a new token and put it into the session token en = generatetoken (); S. setattribute ("csrftoken", Token en); chain. dofilter (request, response);} else {// obtain csrftoken string xhrtoken = req from the HTTP header. getheader ("csrftoken"); // Request Parameters Obtain csrftoken string ptoken = Req. getparameter ("csrftoken"); If (token en! = NULL & xhrtoken! = NULL & stoken. Equals (xhrtoken) {chain. dofilter (request, response);} else if (stoken! = NULL & ptoken! = NULL & stoken. equals (ptoken) {chain. dofilter (request, response);} else {request. getrequestdispatcher ("error. JSP "). forward (request, response );}}

 

First, check whether there is a csrftoken In the session. If there is no csrftoken, it is regarded as the first access and the session is newly created. Then a new token is generated, stored in the session, and the request is executed. If csrftoken already exists in the session, it indicates that the user has established an active session with the server. In this case, check whether the token is included in the request, because the request may come from regular access or XMLHttpRequest asynchronous access, we try to obtain the csrftoken parameter from the request and the csrftoken custom attribute from the HTTP header respectively and compare it with the value in the session, if there is a valid token, the request is valid and can be executed. Otherwise, the request is redirected to the error page. There are many methods to generate token, and any random algorithm can be used. The Java UUID class is also a good choice.

In addition to using filter on the server to verify the token value, we also need to append this token to each request on the client, this is to use js to append the csrftoken code to the link and form request address in HTML. the token is defined as a global variable and its value can be obtained from the session.


Listing 3. attaching a token to a request on the client

Function appendtoken () {updateforms (); updatetags ();} function updateforms () {// obtain all form elements on the page var forms = document. getelementsbytagname ('form'); for (I = 0; I <forms. length; I ++) {var url = forms [I]. action; // if the form's action value is null, no csrftoken if (url = NULL | url = "") Continue is attached. // The input element is dynamically generated, vaR E = document. createelement ("input"); E. name = "csrftoken"; E. value = token; e. Type = "hidden"; forms [I]. appendchild (e) ;}} function updatetags () {var all = document. getelementsbytagname ('A'); var Len = All. length; // traverse all a elements for (VAR I = 0; I <Len; I ++) {var E = All [I]; updatetag (E, 'href ', token) ;}} function updatetag (element, ATTR, token) {var location = element. getattribute (ATTR); If (location! = NULL & location! = ''') {Var fragmentindex = location. indexof ('#'); var fragment = NULL; If (fragmentindex! =-1) {// The URL contains only equivalent pages of the anchor mark fragment = location. substring (fragmentindex); location = location. substring (0, fragmentindex);} var Index = location. indexof ('? '); If (index! =-1) {// The URL contains other parameters: Location = location + '& csrftoken =' + token ;} else {// no other parameter location = location + 'in the URL '? Csrftoken = '+ token;} If (fragment! = NULL) {location + = fragment;} element. setattribute (ATTR, location );}}

 

In the client HTML, the token must be added in two aspects: Form and link. This code first traverses all the forms, adds a hidden field at the end of the form, and puts the csrftoken in it. Then, the Code traverses all links and marks a, and adds the csrftoken parameter to its href attribute. Note that for a. href, this attribute may already have parameters or an anchor. Therefore, the csrftoken must be added in different formats.

If your website uses XMLHttpRequest, you also need to customize the csrftoken attribute in the HTTP header. Use dojo. xhr to add the custom attribute code to XMLHttpRequest as follows:


Listing 4. Custom Attributes in the HTTP Header

VaR plainxhr = dojo. xhr; // rewrite dojo. xhr method dojo. xhr = function (method, argS, hasbody) {// ensure that the header object contains args. headers = args. header | |{}; tokenvalue = '<% = request. getsession (false ). getattribute ("csrftoken") %> '; var token = dojo. getObject ("tokenvalue"); // put the csrftoken attribute in the header args. headers ["csrftoken"] = (token )? Token: ""; return plainxhr (method, argS, hasbody );};

 

Dojo is rewritten here. the xhr method first ensures that dojo. an HTTP header exists in xhr, and then in args. add the csrftoken field to headers and extract the token value from the session and put it into the field.

 

Selection of csrf defense methods

According to the above discussion, the industry has some restraint methods to cope with csrf attacks, but each method has advantages and disadvantages, and none of them is perfect. It is important to select an appropriate method. If the website is an existing system and you want to obtain a certain degree of csrf protection in the shortest time, the Referer verification method is the most convenient. To increase security, you can choose not to support earlier browsers. After all, for the moment, Referer values of IE7 + and ff3 + browsers cannot be tampered.

If the system must support IE6 and still require high security. In most cases, it is not appropriate to use XMLHttpRequest for verification. Token can only be placed in the request as a parameter. If your system does not support publishing information by the user, this level of protection is sufficient. Otherwise, it is still difficult for you to prevent tokens from being stolen and attacked by hackers. In this case, you need to carefully plan the various services provided by your website, find out the parts in the middle that allow users to publish their own information, and separate them from other services, use different tokens to protect your services. This effectively defends against cyberattacks against your critical services and minimizes the risks. After all, deleting a post is much less serious than transferring a large deposit from another account.

If you are developing a brand new system, the choice to defend against csrf is much larger. I suggest you try to use XMLHttpRequest for access to important services. It is much easier to add tokens. In addition, avoid using complex logic in JS Code to construct regular synchronous requests to access resources that require csrf protection, such as window. location and document. createelement ("A") can also reduce unnecessary troubles when adding token.

Finally, remember that csrf is not the only attack method for hackers. No matter how strict your csrf is, if your system has other security vulnerabilities, such as XSS attacks, then hackers can bypass your security protection and launch various attacks, including csrf. Your defense will be like a false one.

 

Summary and prospects

It can be seen that csrf is an attack that is very harmful and difficult to prevent. Although several defense policies can defend against csrf attacks to a large extent, there is no perfect solution. Some new solutions are under research. For example, different dynamic passwords are used for each request, the Referer and Token solutions are combined, and even the HTTP specification is modified, however, these new solutions are not yet mature. It may take a few days to officially put them into use and be widely accepted by the industry. Before that, we can minimize the harm of csrf only by paying full attention to csrf and selecting the most appropriate policy based on the actual situation of the system.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.