How to Prevent CSRF Attacks

background

With the rapid development of the Internet, information security issues have become one of the most concerned focuses of enterprises, and the front-end is a high-risk stronghold that causes enterprise security issues. In the mobile Internet era, in addition to traditional security issues such as XSS and CSRF, front-end personnel often encounter new security issues such as network hijacking and illegal calls to Hybrid APIs. Of course, the browser itself is also constantly evolving and developing, and new technologies such as CSP and Same-Site Cookies are constantly being introduced to enhance security, but there are still many potential threats, which require front-end technicians to constantly "check for leaks and make up for gaps".

front-end security

In recent years, with the rapid development of Meituan's business, the front-end has faced many security challenges, so it has accumulated a lot of practical experience. We have sorted out common front-end security problems and corresponding solutions, and will make a series, hoping to help front-end students continuously prevent and repair security vulnerabilities in daily development. This article is the second in the series.

Today we will explain CSRF. In fact, compared with XSS, CSRF does not seem to be so famous. Many people think that "CSRF is not so destructive". Is it really? Next, we still invite classmate Xiao Ming to "shine" on stage again.

CSRF attack

Occurrence of CSRF Vulnerabilities

Compared with XSS, the reputation of CSRF does not seem to be so big, and many people think that CSRF is "less destructive". Is it really?

Xiao Ming will be invited to appear next~~

Xiao Ming's tragic experience

On this day, classmate Xiao Ming scrolled through Gmail in boredom. Most of them are unnutritive notifications, verification codes, chat records and the like. But there was an email that caught Xiao Ming's attention:

Sell ​​bitcoins, only 998 for one! !

Of course the smart Xiao Ming knew that this was definitely a liar, but he clicked in with a curious attitude (please do not imitate). Sure enough, it was just a blank page with nothing, and Xiao Ming closed the page in disappointment. Nothing seems to happen...

Under this calm appearance, the hacker's attack has already succeeded. In Xiaoming's Gmail, a filtering rule was secretly set up, which made all emails be automatically forwarded to [email protected]. Xiao Ming is still checking emails, but he doesn't know that his emails are being forwarded to the hacker's mailbox like a wild horse.

One day not long after, Xiao Ming discovered that his domain name had been transferred. The ignorant Xiao Ming thought that the domain name expired and he forgot to renew it. It was not until one day that the other party offered a redemption price of $650 that Xiao Ming began to feel that something was wrong.

Xiao Ming carefully checked the transfer of the domain name. The other party has his own verification code, and the verification code of the domain name only exists in his mailbox. Xiao Ming recalled the strange link that day, and re-viewed the source code of the "blank page" after opening it:

<form method="POST" action="https://mail.google.com/mail/h/ewt1jmuj4ddv/?v=prf" enctype="multipart/form-data"> 
    <input type="hidden" name="cf2_emc" value="true"/> 
    <input type="hidden" name="cf2_email" value="[email protected]"/> 
    .....
    <input type="hidden" name="irf" value="on"/> 
    <input type="hidden" name="nvp_bu_cftb" value="Create Filter"/> 
</form> 
<script> 
    document.forms[0].submit();
</script>

Whenever this page is opened, it will send a post request to Gmail. In the request, the "Create Filter" command was executed to forward all emails to "[email protected]".

Xiao Ming has just logged in to Gmail, so when this request is sent, it carries Xiao Ming’s login credentials (Cookie). The background of Gmail receives the request and verifies that there is indeed Xiao Ming’s login credentials, so he successfully configures the filter for Xiao Ming.

Hackers can view all of Xiao Ming's emails, including private information such as domain name verification codes in the emails. After getting the verification code, the hacker can ask the domain name service provider to reset the domain name to himself.

Xiao Ming quickly opened Gmail, found the filter, and deleted it. However, the emails that have been leaked, the domain names that have been transferred, can no longer be retrieved...

The above is the tragic experience of Xiao Ming. And "click on a hacker's link, and all emails will be stolen" is not fabricated. The prototype of this incident is the CSRF vulnerability of Gmail in 2007:

https://www.davidairey.com/google-Gmail-security-hijack/

Of course, this vulnerability has been fixed by Gmail, please do not panic if you use Gmail.

What is CSRF

CSRF (Cross-site request forgery) Cross-site request forgery: The attacker induces the victim to enter a third-party website, and in the third-party website, sends a cross-site request to the attacked website. Use the registration credentials that the victim has obtained on the attacked website to bypass the user verification in the background, and achieve the purpose of impersonating the user to perform an operation on the attacked website.

A typical CSRF attack has the following process:

  • The victim logs into a.com and keeps the login credentials (cookies).
  • The attacker lures the victim to visit b.com.
  • b.com sends a request to a.com: a.com/act=xx. The browser will carry the cookie of a.com by default.
  • After receiving the request, a.com verifies the request and confirms that it is the victim's credentials, mistaking it for the request sent by the victim himself.
  • a.com executed act=xx on behalf of the victim.
  • The attack is completed, and the attacker pretends to be the victim without the victim's knowledge, and makes a.com perform the operation he defined.

Several common attack types

CSRF of type GET

The use of CSRF of GET type is very simple, only one HTTP request is required, and it is generally used like this:

![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/ff0cdbee.example/withdraw?amount=10000&for=hacker)

After the victim visits the page containing this img, the browser will automatically send an HTTP request to http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker. bank.example will receive a cross-origin request containing the victim's login information.

CSRF of POST type

This type of CSRF is usually exploited using an auto-submitted form, such as:

<form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script> 

After visiting the page, the form will be automatically submitted, which is equivalent to simulating the user completing a POST operation.

POST-type attacks are usually a little stricter than GET, but still not sophisticated. Any personal website, blog, or website that has been uploaded by hackers may be the source of the attack, and the back-end interface cannot rely on the security of only allowing POST.

Link Type CSRF

Link-type CSRF is not common. Compared with the other two cases where the user opens the page and is recruited, this kind of situation requires the user to click the link to trigger. This type is usually to embed malicious links in pictures posted on forums, or to induce users to be recruited in the form of advertisements. Attackers usually use exaggerated words to trick users into clicking, for example:

  <a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!
  <a/>

Since the user logged in to the trusted website A before and saved the login status, as long as the user actively visits the above PHP page, the attack is successful.

Features of CSRF

  • Attacks are generally launched on third-party websites, not the attacked website. A compromised website cannot prevent the attack from happening.
  • The attack uses the victim's login credentials on the attacked website to impersonate the victim to submit operations; instead of directly stealing data.
  • During the whole process, the attacker cannot obtain the victim's login credentials, but only "false use".
  • Cross-site requests can be made in various ways: image URL, hyperlink, CORS, Form submission, etc. Some request methods can be directly embedded in third-party forums and articles, making it difficult to track.

CSRF is usually cross-domain, because foreign domains are usually easier for attackers to control. However, if there are functions that are easy to be exploited in this domain, such as forums and comment areas where pictures and links can be posted, attacks can be carried out directly in this domain, and this kind of attack is even more dangerous.

Defense strategy

CSRF is usually initiated from a third-party website. The attacked website cannot prevent the attack from happening. It can only improve its security by enhancing its own website's protection against CSRF.

Two characteristics of CSRF are mentioned above:

  • CSRF (usually) happens on third-party domains.
  • CSRF attackers cannot obtain information such as cookies, but only use them.

In view of these two points, we can specifically formulate protection strategies, as follows:

  • Block access from unknown foreign domains
  • homology detection
  • Samesite Cookie
  • Information that requires this field to be attached when submitting
  • CSRF Token
  • Double Cookie Authentication

Below we describe various protection methods in detail.

homology detection

Since most CSRFs come from third-party websites, we directly prohibit external domains (or untrusted domain names) from making requests to us.

So the question is, how do we judge whether the request comes from a foreign domain?

In the HTTP protocol, each asynchronous request will carry two headers, which are used to mark the source domain name:

  • Origin Header
  • Refer Header

When the browser initiates a request, these two headers will be automatically brought in in most cases, and the content cannot be customized by the front end. The server can determine the source domain of the request by analyzing the domain names in the two headers.

Use the Origin Header to determine the origin domain name

In some requests related to CSRF, the Origin field will be carried in the header of the request. The field contains the requested domain name (excluding path and query).

If Origin exists, you can directly use the field in Origin to confirm the source domain name.

But Origin does not exist in the following two cases:

  • IE11 same-origin policy: IE 11 will not add the Origin header to cross-site CORS requests, and the Referer header will still be the only identifier. The most fundamental reason is that IE 11 defines the same origin differently from other browsers. There are two main differences. You can refer to MDN Same-origin_policy#IE_Exceptions

  • 302 redirection: Origin is not included in the redirected request after 302 redirection, because Origin may be considered sensitive information from other sources. In the case of 302 redirection, it is directed to the URL on the new server, so the browser does not want to leak the Origin to the new server.

Use Referer Header to determine source domain name

According to the HTTP protocol, there is a field called Referer in the HTTP header, which records the source address of the HTTP request. For resource requests such as Ajax requests, pictures and scripts, Referer is the address of the page that initiated the request. For page jumps, Referer is the address of the previous page that opened the page history. Therefore, we can use the Origin part of the link in Referer to know the source domain name of the request.

This method is not foolproof. The value of Referer is provided by the browser. Although there are clear requirements in the HTTP protocol, each browser may have different implementations of Referer, which does not guarantee that the browser itself has no security holes. Using the method of verifying the Referer value is to rely on the third party (namely the browser) to guarantee the security. In theory, this is not very safe. In some cases, attackers can hide or even modify the Referer they request.

In 2014, W3C's Web Application Security Working Group released the Referrer Policy draft, which made detailed regulations on how browsers should send Referer. As of now, most of the new browsers have supported this draft, and we can finally flexibly control the Referer strategy of our website. The new version of Referrer Policy specifies five Referrer policies: No Referrer, No Referrer When Downgrade, Origin Only, Origin When Cross-origin, and Unsafe URL. The three strategies that existed before: never, default, and always, have changed their names in the new standard. Their corresponding relationship is as follows:

policy name property value (new) attribute value (old)
No Referrer no-referrer never
No Referrer When Downgrade no-Referrer-when-downgrade default
Origin Only (same or strict) origin origin
Origin When Cross Origin (strict) origin-when-crossorigin -
Unsafe URL unsafe-url always

According to the above table, it is necessary to set the Referrer Policy to same-origin. For links and references of the same origin, a Referer will be sent, and the referer value is Host without Path; cross-domain access does not carry a Referer. For example: aaa.com refers to the resource of bbb.com, no Referer will be sent.

There are three ways to set Referrer Policy:

  • In CSP settings
  • Add meta tags to page header
  • a tag adds referrerpolicy attribute

There are many things mentioned above, but we can know one problem: attackers can hide Referer in their own requests. If the attacker fills in his request like this:

![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/ff0cdbee.example/withdraw?amount=10000&for=hacker)

Then the attack initiated by this request will not carry the Referer.

In addition, the Referer does not have or is not credible in the following cases:

  • Using window.location.href=url to jump to the interface under IE6 and 7 will lose the Referer.
  • When using window.open under IE6 and 7, the Referer will also be missing.
  • The HTTPS page jumps to the HTTP page, and all browser Referers are lost.
  • When clicking on Flash to reach another website, the situation of Referer is messy and unreliable.

Unable to confirm the source domain name

What should I do when the Origin and Referer header files do not exist? If neither Origin nor Referer exists, it is recommended to block directly, especially if you are not using a random CSRF Token (see below) as a second check.

How to block foreign domain requests

Through the verification of the Header, we can know the source domain name of the request. These source domain names may be the domain name of the website, or a subdomain name, or an authorized third-party domain name, or an untrustworthy unknown domain name.

We already know whether the requested domain name is from an untrusted domain name, can we prevent CSRF attacks by directly blocking these requests?

wait! When a request is a page request (such as the homepage of a website), and the source is a link of a search engine (such as Baidu's search results), it will also be regarded as a suspected CSRF attack. Therefore, it is necessary to filter out the page request when judging. Usually, the Header meets the following conditions:

Accept: text/html
Method: GET

But correspondingly, the page request is exposed to the scope of CSRF attack. If you do something to the current user in the GET request of the page in your website, the prevention will fail.

For example, the following page request:

GET https://example.com/addComment?comment=XXX&dest=orderId

Note: Strictly speaking, there is not necessarily a risk of CSRF attacks, but there are still many websites that often attach parameters to the main document GET request to achieve product functions, but this is a security risk for itself.

In addition, as mentioned earlier, CSRF comes from third-party domain names in most cases, but it does not rule out the origination of this domain. If an attacker has permission to publish comments (including links, pictures, etc., collectively referred to as UGC) in this domain, he can directly launch an attack on this domain. In this case, the same-origin policy cannot achieve the protective effect.

To sum up: Same-origin verification is a relatively simple defense method that can prevent most CSRF attacks. But this is not foolproof. For websites with higher security requirements or with more user input content, we need to take additional protective measures for key interfaces.

CSRF Token

Another feature of CSRF mentioned earlier is that attackers cannot directly steal user information (Cookie, Header, website content, etc.), but only use the information in the cookie.

The reason why the CSRF attack can be successful is that the server mistakenly regards the request sent by the attacker as the user's own request. Then we can require all user requests to carry a Token that CSRF attackers cannot obtain. The server distinguishes normal requests from attack requests by verifying whether the request carries the correct Token, and can also prevent CSRF attacks.

principle

The protection strategy of CSRF Token is divided into three steps:

  1. Output CSRF Token to the page

First of all, when the user opens the page, the server needs to generate a Token for the user. The Token encrypts the data through an encryption algorithm. Generally, the Token includes a combination of random strings and timestamps. Obviously, the Token can no longer be placed in the Cookie when submitting. Otherwise, it will be used by the attacker again. Therefore, for the sake of safety, it is best to store the Token in the session of the server, and then use JS to traverse the entire DOM tree every time the page is loaded, and add the Token after all a and form tags in the DOM. This can solve most of the requests, but for the HTML code that is dynamically generated after the page is loaded, this method has no effect, and the programmer needs to manually add Token when coding.

  1. The request submitted by the page carries this Token

For GET requests, Token will be appended to the request address, so that the URL becomes http://url?csrftoken=tokenvalue. For POST requests, add at the end of the form:

<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>

In this way, the Token is added to the request as a parameter.

  1. The server verifies whether the Token is correct

When the user obtains the Token from the client and submits it to the server again, the server needs to judge the validity of the Token. The verification process is to decrypt the Token first, and compare the encrypted string and the timestamp. If the encrypted string is consistent and the time has not expired, then This Token is valid.

This method is safer than checking the Referer or Origin before. The Token can be generated and placed in the Session, and then the Token is taken out of the Session at each request and compared with the Token in the request, but this The more troublesome part of this method is how to add Token to the request as a parameter.

The following will take Java as an example to introduce some server-side verification logic of CSRF Token. The code is as follows:

HttpServletRequest req = (HttpServletRequest)request; 
HttpSession s = req.getSession(); 
 
// 从 session 中得到 csrftoken 属性
String sToken = (String)s.getAttribute(“csrftoken”); 
if(sToken == null){ 
   // 产生新的 token 放入 session 中
   sToken = generateToken(); 
   s.setAttribute(“csrftoken”,sToken); 
   chain.doFilter(request, response); 
} else{ 
   // 从 HTTP 头中取得 csrftoken 
   String xhrToken = req.getHeader(“csrftoken”); 
   // 从请求参数中取得 csrftoken 
   String pToken = req.getParameter(“csrftoken”); 
   if(sToken != 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); 
   } 
}

Code sourced from IBM developerworks CSRF

The value of this Token must be randomly generated so that it cannot be guessed by an attacker. Consider utilizing the java.security.SecureRandom class of a Java application to generate a sufficiently long random token. Alternative generation algorithms include using 256-bit BASE64 encoding Hashes, developers who choose this generation algorithm must ensure that randomness and uniqueness are used in the hashed data to generate random identities. Usually, developers only need to generate a token once for the current session. After the initial generation of this token, the value will be stored in the session and used for each subsequent request until the session expires. When an end user makes a request, the server must verify the existence and validity of the token in the request, comparing it to the token found in the session. If the token is not found in the request, or the provided value does not match the value in the session, the request should be aborted, the token should be reset and the event logged as a potential CSRF attack in progress.

Distributed verification

In a large website, using Session to store CSRF Token will bring a lot of pressure. Access to a single server session is the same. But in today's large-scale websites, we usually have more than one server, there may be dozens or even hundreds of servers, and even multiple computer rooms may be in different provinces. HTTP requests initiated by users usually go through Ngnix and the like After the load balancer, it is routed to the specific server. Since the Session is stored in the memory of the stand-alone server by default, multiple HTTP requests sent by the same user in a distributed environment may fall on different servers one after another, resulting in The HTTP request initiated later cannot get the Session data stored in the server by the previous HTTP request, which makes the Session mechanism invalid in a distributed environment. Therefore, CSRF Token needs to be stored in a public storage space such as Redis in a distributed cluster.

Since using Session storage, reading and verifying CSRF Token will cause relatively large complexity and performance problems, many websites currently use the Encrypted Token Pattern method. The Token of this method is a calculated result, not a randomly generated string. In this way, there is no need to read the stored Token during verification, and only need to calculate it again.

The value of this Token is usually generated by encryption using UserID, timestamp and random number. This can not only ensure that the Token of the distributed service is consistent, but also ensure that the Token is not easy to be cracked.

After the token is successfully decrypted, the server can access the parsed value, and the UserID and timestamp contained in the Token will be used to verify the validity. The UserID is compared with the currently logged-in UserID, and the timestamp is compared with the current time.

Summarize

Token is a relatively effective CSRF protection method. As long as there is no XSS vulnerability on the page to leak Token, the CSRF attack on the interface will not succeed.

However, the implementation of this method is more complicated. Token needs to be written to each page (the front end cannot use pure static pages), and each Form and Ajax request carries this Token. The backend verifies each interface and guarantees The page Token is the same as the request Token. This makes it impossible for this protection strategy to intercept and process in a unified way on general interception, but requires adding corresponding output and verification for each page and interface. This method is a huge amount of work and may be missed.

Verification codes and passwords can also function as CSRF tokens, and are more secure.

Why do many banks and other websites require users who have already logged in to enter their passwords again when transferring money? Does it make sense now?

Double Cookie Authentication

It is cumbersome to store CSRF Token in the session, and all interfaces cannot be uniformly processed on the general interception.

Then another defense is to use a double submit cookie. Taking advantage of the fact that CSRF attacks cannot obtain user cookies, we can require Ajax and form requests to carry a value in a cookie.

Double cookies use the following process:

  • When a user visits a website page, a cookie is injected into the requesting domain name, and the content is a random string (for example, csrfcookie=v8g9e4ksfhw).
  • When the front end initiates a request to the back end, take out the cookie and add it to the parameters of the URL (continued from the above example POST https://www.a.com/comment?csrfcookie=v8g9e4ksfhw).
  • The backend interface verifies whether the field in the cookie is consistent with the field in the URL parameter, and rejects if they are inconsistent.

This method is much simpler than CSRF Token. It can be realized directly through the method of front-end and back-end interception. The back-end verification is also more convenient. It only needs to compare the fields in the request, and there is no need to query and store the Token.

Of course, this method has not been applied on a large scale, and its security on large websites is still not as high as that of CSRF Token. Let us give an example to illustrate the reason.

Since any cross-domain will cause the front end to be unable to obtain the fields in the cookie (including between sub-domain names), the following situation occurs:

  • If the website that the user visits is www.a.com, and the api domain name of the backend is api.a.com. Then under www.a.com, the front end cannot get the cookie of api.a.com, and it cannot complete double cookie authentication.
  • So this authentication cookie must be planted under a.com, so that every subdomain can be accessed.
  • Any subdomain can modify cookies under a.com.
  • A subdomain has a vulnerability and is attacked by XSS (for example, upload.a.com). Although there is no information worth stealing under this subdomain. But the attacker modified the Cookie under a.com.
  • The attacker can directly use the cookie configured by himself to launch a CSRF attack on the user who has been attacked by XSS and log in to www.a.com.

Summary:
Advantages of using double cookies to defend against CSRF:

  • There is no need to use Session, which is more applicable and easy to implement.
  • Token is stored in the client and will not put pressure on the server.
  • Compared with Token, the implementation cost is lower, and the verification can be intercepted uniformly at the front and back ends, without adding interfaces and pages one by one.

shortcoming:

  • Additional fields are added to the cookie.
  • If there are other vulnerabilities (such as XSS), the attacker can inject cookies, then this defense method will fail.
  • It is difficult to isolate subdomains.
  • In order to ensure the security of cookie transmission, it is best to use this defense method to ensure that the entire site HTTPS is used. If HTTPS is not used, this method will also be risky.

Samesite Cookie Attribute

The way to prevent CSRF attacks already has the above preventive measures. In order to solve this problem from the source, Google drafted a draft to improve the HTTP protocol, which is to add a Samesite attribute to the Set-Cookie response header, which is used to indicate that the cookie is a "same site cookie". As a first-party cookie, it cannot be used as a third-party cookie. Samesite has two attribute values, namely Strict and Lax, which are explained below:

Samesite=Strict

This is called strict mode, which means that this cookie cannot be used as a third-party cookie under any circumstances, without exception. For example, b.com sets the following cookies:

Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3

We initiate any request to b.com under a.com, the cookie foo will not be included in the Cookie request header, but bar will. To give a practical example, if the cookie used by the Taobao website to identify whether the user is logged in or not is set to Samesite=Strict, then after the user clicks on the link from the Baidu search page or even the Tmall page to enter Taobao, Taobao will not be logged in. status, because Taobao's server will not accept that cookie, and any request to Taobao initiated by other websites will not bring that cookie.

Samesite=Lax

This is called loose mode, which is a bit looser than Strict: if the request is this kind of request (changing the current page or opening a new page) and it is a GET request at the same time, then this cookie can be used as a third-party cookie. For example, b.com sets the following cookies:

Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3

When a user clicks a link from a.com to enter b.com, the cookie foo will not be included in the Cookie request header, but bar and baz will, which means that the user will not be affected by link jumping between different websites up. But if the request is an asynchronous request from a.com to b.com, or the page jump is triggered by the post submission of the form, the bar will not be sent.

Generate Token and put it in Cookie and set Samesite of Cookie, the Java code is as follows:

 private void addTokenCookieAndHeader(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
        //生成token
        String sToken = this.generateToken();
        //手动添加Cookie实现支持“Samesite=strict”
        //Cookie添加双重验证
        String CookieSpec = String.format("%s=%s; Path=%s; HttpOnly; Samesite=Strict", this.determineCookieName(httpRequest), sToken, httpRequest.getRequestURI());
        httpResponse.addHeader("Set-Cookie", CookieSpec);
        httpResponse.setHeader(CSRF_TOKEN_NAME, token);
    }

Code from OWASP Cross-Site_Request_Forgery #Implementation example

How should we use SamesiteCookie

If SamesiteCookie is set to Strict, the browser will not carry cookies in any cross-domain requests, and will not carry cookies when new tabs are reopened, so there is basically no chance for CSRF attacks.

However, if you jump to a sub-domain name or reopen the newly logged-in website in a new tab, the previous cookies will not exist. Especially for websites with logins, we need to log in again when we open a new tab to enter, or jump to a website with a subdomain. For users, the experience may not be very good.

If SamesiteCookie is set to Lax, then other websites can use cookies when they jump from the page, which can guarantee the user's login status when the page is opened by an external domain connection. But correspondingly, its security is relatively low.

Another problem is that the compatibility of Samesite is not very good. In addition to the new version of Chrome and Firefox, Safari and iOS Safari do not support it at this stage. It seems that it cannot be popularized at this stage.

Moreover, SamesiteCookie currently has a fatal flaw: it does not support subdomains. For example, a cookie planted under topic.a.com cannot use a SamesiteCookie planted under a.com. As a result, when our website has multiple subdomains, SamesiteCookie cannot be used to store user login information in the main domain name. Each subdomain requires the user to log in again.

In short, SamesiteCookie is a possible alternative to same-origin verification, but it is not yet mature, and its application scenarios remain to be seen.

Prevent website from being exploited

What I said above is how to protect the attacked website. Instead of preventing attacks from happening, CSRF attacks can come from:

  • Attacker's own website.
  • Sites with file upload vulnerabilities.
  • Third-party forums and other user content.
  • The comment function of the attacked website itself, etc.

We cannot protect against websites from hackers themselves. But for other situations, how to prevent your own website from being used as the source of the attack?

  • Strictly manage all upload interfaces to prevent any unexpected upload content (such as HTML).
  • Add Header X-Content-Type-Options: nosniff to prevent hackers from uploading HTML content resources (such as pictures) from being parsed as web pages.
  • For the pictures uploaded by users, transfer or verify them. Do not directly use user-filled image links.
  • When the current user opens the link filled in by other users, the risk needs to be informed (this is one of the reasons why many forums do not allow direct posting of external domain links in the content, not only for user retention, but also for security considerations).

Other CSRF prevention measures

For front-line programmers, we can use various protection strategies to defend against CSRF. For QA, SRE, and security leaders, what can we do to improve security?

CSRF test

CSRFTester is a testing tool for CSRF vulnerabilities. The testing principle of the CSRFTester tool is roughly like this. Use a proxy to capture all the connections and all forms we have visited in the browser, and modify the corresponding forms in CSRFTester. Waiting for information and resubmitting is equivalent to a forged client request. If the modified test request is successfully accepted by the website server, it means that there is a CSRF vulnerability. Of course, this tool can also be used to carry out CSRF attacks. The method of using CSRFTester is roughly divided into the following steps:

Step 1: Set browser proxy

CSRFTester uses port 8008 on Localhost as its proxy by default, and if the proxy configuration is successful, CSRFTester will generate debug messages for all subsequent HTTP requests made by your browser.

Step 2: Visit the website with a legitimate account to start testing

We need to find a specific business web page that we want to test for CSRF. After finding this page, select the "Start Recording" button in CSRFTester and execute the business function; after finishing, click the "Stop Recording" button in CSRFTester; under normal circumstances, the software will traverse all the requests of the current page.

Step 3: Modify and forge the request via CSRF

After that, we will find that there are a series of record requests running out on the software, these are all GET or POST requests generated by our browser when performing business functions. By selecting a row in the list, we can now modify the parameters used to perform business functions, and modify the query and form parameters by clicking the corresponding request. After modifying all the final submission values ​​​​we want to induce users to form, you can choose to start generating HTML reports.

Step 4: Get the result and repair it if there are any loopholes

First a "Report Type" must be selected. The report type determines how we want the victim browser to submit previously logged requests. There are currently 5 possible reports: Form, iFrame, IMG, XHR and Link. Once the report type is selected, we can choose to start the newly generated report in the browser, and finally perform corresponding troubleshooting and repair according to the report.

CSRF monitoring

For a relatively complex website system, it is very possible that some projects, pages, and interfaces miss CSRF protection measures.

Once a CSRF attack occurs, how do we discover these attacks in time?

CSRF attacks have obvious characteristics:

  • Cross domain request.
  • The MIME type of the GET type request header is probably an image, but the MIME type of the actually returned header is Text, JSON, and HTML.
    We can monitor all interface requests at the proxy layer of the website. If the request meets the above characteristics, it can be considered that the request is suspected of CSRF attack. We can remind the corresponding page and project leader to check or review their CSRF protection strategy.

Recommendations for individual user CSRF security

Individual users who frequently surf the Internet can use the following methods to protect themselves:

Browsing email or news using the web version of email also brings additional risks, because viewing email or news messages may lead to malicious code attacks.
Try not to open suspicious links, and be sure to use a browser that is not commonly used when opening.

Summarize

A brief summary of the above defense strategies:

  • CSRF automatic defense strategy: same-origin detection (Origin and Referer verification).
  • CSRF active defense measures: Token verification or double cookie verification and cooperation with Samesite Cookie.
  • To ensure the idempotence of the page, the back-end interface should not perform user operations on the GET page.

In order to better defend against CSRF, the best practice should be to comprehensively consider the advantages and disadvantages of the defense measures summarized above, and make an appropriate choice in combination with the current web application itself, so as to better prevent the occurrence of CSRF.

Historical case

WordPress CSRF Vulnerability

In March 2012, WordPress discovered a CSRF vulnerability that affected version 3.3.1 of WordPress. WordPress is a well-known blogging platform. This vulnerability can allow attackers to modify the title of a Post, add users with administrative rights, and operate user accounts, including But not limited to deleting comments, modifying avatars, etc. The specific list is as follows:

  • Add Admin/User
  • Delete Admin/User
  • Approve comment
  • Unapprove comment
  • Delete comment
  • Change background image
  • Insert custom header image
  • Change site title
  • Change administrator’s email
  • Change Wordpress Address
  • Change Site Address

Then this vulnerability is actually that the attacker guides the user to enter the target WordPress first, and then clicks a button on the phishing site. This button is actually a form submission button, which will trigger the submission of the form. Authorized users, the implementation code is as follows:

<html> 
<body onload="javascript:document.forms[0].submit()"> 
<H2>CSRF Exploit to add Administrator</H2> 
<form method="POST" name="form0" action="http://<wordpress_ip>:80/wp-admin/user-new.php"> 
<input type="hidden" name="action" value="createuser"/> 
<input type="hidden" name="_wpnonce_create-user" value="<sniffed_value>"/> 
<input type="hidden" name="_wp_http_referer" value="%2Fwordpress%2Fwp-admin%2Fuser-new.php"/> 
<input type="hidden" name="user_login" value="admin2"/> 
<input type="hidden" name="email" value="[email protected]"/> 
<input type="hidden" name="first_name" value="[email protected]"/> 
<input type="hidden" name="last_name" value=""/> 
<input type="hidden" name="url" value=""/> 
<input type="hidden" name="pass1" value="password"/> 
<input type="hidden" name="pass2" value="password"/> 
<input type="hidden" name="role" value="administrator"/> 
<input type="hidden" name="createuser" value="Add+New+User+"/> 
</form> 
</body> 
</html> 

YouTube CSRF Vulnerability

In 2008, security researchers discovered that almost all actions that users can operate on YouTube have CSRF vulnerabilities. If the attacker has added the video to the user's "Favorites", then he can add himself to the user's "Friend" or "Family" lists, send arbitrary messages on behalf of the user, mark the video as inappropriate, Automatically share a video with the user's contacts. For example, to add a video to a user's "Favorites," an attacker would simply embed an IMG tag like the following on any site:

<img src="http://youtube.com/watch_ajax?action_add_favorite_playlist=1&video_
id=[VIDEO ID]&playlist_id=&add_to_favorite=1&show=1&button=AddvideoasFavorite"/>

Attackers may have exploited this vulnerability to increase the popularity of the video. For example, add a video to enough users' "Favorites" and YouTube will display that video as a "Top Favorites". In addition to boosting a video's popularity, an attacker could cause users to unknowingly mark a video as "inappropriate," causing YouTube to remove the video.

These attacks may also have been used to violate user privacy. YouTube allows users to limit certain videos to friends or relatives. These exploits would cause an attacker to add it to a user's "Friend" or "Family" list, giving them access to all private videos that would otherwise be restricted to users in the friends and relatives list.

An attacker can also share a video with all of the user's contact list ("Friends", "Family", etc.), "sharing" means sending them a link to the video, with the option of attaching a message of course. The link in this message is no longer a video link in the true sense, but an offensive website link, which is likely to be clicked by users, which makes the attack viral.

Guess you like

Origin blog.csdn.net/qq_32907491/article/details/132196635