Cross Site Request Forgery (CSRF)

Defending Against Cross Site Request Forgery

 

Cross-Site Request Forgery, or CSRF, sometimes pronounced “Sea Surf,” is an alarmingly simple way to perform unauthorized actions on a website. The trick is this: The user is logged into a restricted site or otherwise has authorization to use it. A URL from a hostile site asks the restricted one to take some action. Not knowing any better, it does.

How CSRF works

Standard defenses don’t stop a CSRF attack. It can go through HTTPS. It can submit a form. Session cookies go right through. All that’s necessary is to know what URL will perform an action, and to get the browser to submit it. There are defenses, but they aren’t the obvious ones.

Suppose the site under attack has a page to change the user’s password. The attacker creates a POST request from another site that mimics the password change form and lures the user to the page, which uses hidden fields and looks harmless. The siteaccepts the form and changes the user’s password to one the attacker chose.

There are many uses for an attack of this type. It could hijack an account, authorize a transfer of money, change a mailing address, or make a purchase. It can’t acquire information from the server, since the response goes back to the user and not the hostile site.

CSRF is different from the similar-sounding cross-site scripting (XSS). XSS means introducing foreign JavaScript onto a page to perform an action the user didn’t intend. CSRF doesn’t have to involve JavaScript. Calling XMLHttpRequest() from the attacker’s page doesn’t work on any major browser today, though it could work on some old browsers.

XSS and CSRF are a deadly tag team. XSS can retrieve information from a site, allowing the attacker to craft a URL with user-specific data. JavaScript can read HTTP responses and forge some headers, so XSS may be able to bypass normal CSRF protection.

CSRF is the evil cousin of Cross-Origin Resource Sharing, or CORS. CORS is a legitimate technique for one domain to process requests from another domain. It can use an XMLHttpRequest call. CORS works only when the server configures a page to accept the request. A server that accepts CORS requests but is misconfigured can be seriously vulnerable to CSRF.

How an attack is launched

The hostile URL needs to get invoked in the user’s browser somehow. These are three common ways:

  • Sending an email message with the URL in a link.
  • Putting the link in a public place, such as a Twitter post or a blog comment.
  • Making the URL the SRC attribute of an IMG tag. This invokes the URL just by viewing the page that contains the “image.”

If it’s used in a mass campaign, it’s most effective with a major website that lots of people are commonly logged in to. Another approach is to use spearphishing email. The message will target a specific individual who is known to have a certain account, using a personally tailored URL.

Real-life examples

In 2010, a CSRF attack on Twitter made users appear to post sexually oriented Tweets. Being able to post the link in a Tweet greatly increased the chances that the victims would be logged in to the site. It used a classic social engineering approach, with “WTF” followed by the link to the hostile site. Twitter shortens links, making it easier to fool victims.

MyBB, a popular open-source application for Web forums, had a vulnerability to a combined XSS and CSRF attack in version 1.8.3. Dingjie Yang demonstrated the vulnerability, but it apparently was never used maliciously. An attacker could have read the session cookie and used it to authenticate a request. Version 1.8.4 fixed the problem in 2015.

CSRF defenses

There are two main defenses against CSRF: URL tokens and HTTP headers.

The first approach includes a token, unique to the user session, in any sensitive requests. If the request has the wrong token or no token, the server should refuse the request. The token needs to be unpredictable. An XSS vulnerability could let an attacker discover the token, but normally this approach is secure and compatible with all browsers.

The second approach relies on the Origin and Referer HTTP headers. The browser generates these, and normally an external website can’t spoof them. The Origin header indicates the domain from which a request came. Unfortunately, older browsers may not support the header, and some current ones don’t issue the header for same-origin requests, which are precisely the ones you want to authenticate. The Referer header provides a fallback, but some people disable referers for privacy reasons. If both headers are missing and forgery is a concern, the site has to rely on tokens or reject the request.

Using POST requests for all sensitive actions provides additional protection. GET requests which include a CSRF token are easier to spy on (e.g., through Referer headers). A POST parameter sent by HTTPS will be very difficult for anyone to steal.

An alternative is the “double submit cookie” approach. A random value is stored both in a cookie and a URL parameter. The server accepts the request only if the two match. An external site can’t read or modify the cookie. The advantage compared to a CSRF token is that it doesn’t require storing the token anywhere; a new one is generated for each request. If the attacker can run from a subdomain of the targeted domain (on a site which allows user subdomains), this approach isn’t secure, since the attacker can forge the cookie.

The best approach is a combined one. CSRF tokens, HTTP headers, HTTPS POST requests, and anti-XSS defenses, all used together, will protect any transactions where forgery could cause trouble. It will be very difficult for an attacker to overcome all the protections. Developers need to keep such attacks in mind when creating a secure site.

CSRF mitigation in ASP .NET applications

In ASP .NET applications, the CSRF vulnerabilities mitigation strategy provided by .NET framework is the use of anti-forgery tokens.

Anti-forgery tokens are generated for each user session and they are included in the request which is made to the server as hidden fields, so a double validation in the server is made using user authentication and the anti-forgery token.

Implementation in Web forms

In Web forms, the use of anti-forgery tokens is based on having enabled EnableViewStateMac attribute and using ViewStateUserKey field to store a unique identifier per session.

EnableViewStateMac attribute is compulsorily enabled since version 4.5.2 of .NET framework, released in September 2014, and there are security patches, whose installation is recommended, for versions from 1.1 to 4.5.2. It is essential to review if security patches are not updated in our system and we have a version previous to 4.5.2, that we do not disable this attribute, neither in the configuration files of the application or any of its pages.

As for ViewStateUserKey, its value can be filled in our pages Page_Init method or in our web applications’s master page, or in our pages’ OnInit method.

 

Implementation in ASP .NET MVC and Web API

In ASP .NET MVC and Web API applications, .NET framework facilitates the creation and validation of anti-forgery tokens.

For creating anti-forgery tokens, we can use the @AntiForgery.GetHtml() method in Razor pager or the @Html.AntiForgeryToken() method in MVC views.

For validation, we can use @AntiForgery.Validate method or include a ValidateAntiForgeryToken attribute in our action or MVC controller.

If you want to extend the built-in functionality provided by ASP .NET, you can use IAntiForgeryAdditionalDataProvider to add additional information to the generated tokens and, subsequently, make the validation deemed necessary.

 

Conclusions

.NET framework offers facilities for efficient protection from CSRF attacks. We have to know what the vulnerability is as well as the built-in mechanisms provided by .NET, to provide our web applications adequate protection.

In Kiuwan Code Analysis we are working to provide the necessary capabilities to detect possible vulnerabilities to CSRF attacks.

 

References:

OWASP Cheat sheet