CORS Demystified!

Background

CORS stands for Cross Origin Resource Sharing. This is security feature supported by Browsers that allows the UI applications to be hosted on a separate domain from the underlying APIs that are used. This is what enables the API Economy work! The consuming applications can call APIs hosted on different domains from different providers to build meaningful applications to the end user. If the UI and API were to be hosted on the same domain, this makes the applications very restrictive in the functionality they can provide as they can only call services that are hosted on the same domain!

Lets talk about how this all started! Long time ago when Dinosaurs were roaming the earth, yeah not so long, but you get the point, browsers allowed AJAX calls only to the domain where the page was loaded from. Let us say that the page was loaded from http://www.xyz.com, the browser would allow AJAX calls back to http://www.xyz.com. The reason they did that was to protect the end user from below scenario.

  1. User logs on to http://www.xyz.com and gets authentication cookie. Let’s call it xyzauthtoken cookie that is scoped to the domain xyz.com
  2. Now the user while logged on to xyz.com navigates to another site, http://www.evil.com
  3. evil.com generates an AJAX request to xyz.com. Browser sends the xyzauthtoken cookie along with the request allowing evil.com to impersonate the user logged in to xyz.com. This is pretty bad!

However as web applications evolved, this security feature made it very restrictive for applications from consuming services/APIs from different providers that are hosted on different domains.

CORS spec was put-together by major Browser providers to solve this problem. Chorme, Safari, Firefox were the early adopters of this security feature where as IE started supporting CORS only from IE version 10 and above!

How does CORS work?

CORS empowers the API providers and allows them to control who can consume their services over AJAX. The below diagram depicts the CORS flow!

  1. User logs on to http://www.xyz.com and gets authentication cookie. Let’s call it xyzauthtoken cookie that is scoped to the domain xyz.com
  2. Let us say, the webapp invokes services hosted on api.123.com to get some data. The user has to authenticate to api.123.com, but that is beyond the scope of this article! Just in case you are curious, OAuth solves that problem, a topic for future blog post!
  3. The CORS supported browser, holds the request and issues something called a pre-flight OPTIONS request to api.123.com with a request header set to Origin=www.xyz.com. The browser does not send any cookies with the preflight request.
  4. Now api.123.com can decide weather to accept a request from xyz.com. If api.123.com is okay serving up a request from xyz.com, it responds with response header, Access-Control-Allow-Origin, that specifies all the domains that can access api.123.com. The header can take regular expressions and if api.123.com can accept requests from any domain, you can set something like Access-Control-Allow-Origin=*.
  5. The browser checks if the value in Access-Control-Allow-Origin matches to the value in Origin. If there is a match, the browser releases the original request to api.123.com
  6. The AJAX request to api.123.com is sent and the app is able to get the data from a service hosted on a different domain!

How does CORS protect the end user?

In the above scenario, lets say api.123.com allows AJAX only from xyz.com and abc.com. The service could have set Access-Control-Allow-Origin header as follows:

Access-Control-Allow-Origin=xyz.com,abc.com

Now, imagine a scenario where the user navigates to http://www.evil.com and the malicious site issues a AJAX request to api.123.com. Let us see how CORS protects the user from this call.

  1. The CORS supported browser, holds the request and issues a pre-flight OPTIONS request to api.123.com with a request header set to Origin=www.evil.com. The browser does not send any cookies with the preflight request.
  2. api.123.com responds with Access-Control-Allow-Origin=xyz.com,abc.com
  3. The browser checks if the value in Access-Control-Allow-Origin matches to the value in Origin. In this case, it does not match and the Browser drops the request and no call is made to api.123.com

CORS spec allows the Provider of any API to specify what Http Methods and Http Headers can be sent by the Consumers and provides flexibility in accepting lets say a GET request from any domain and restrict a PUT/POST to only a sub-set of trusted domains.  If you need more information on CORS and all the features supported by CORS, it is well documented here!

Next time you are Banking or checking your investments online, turn on Developer Tools (F12) in your browser and see how the AJAX calls are being handled!

Advertisements

CSRF Defense for REST API

What is CSRF?

CSRF stands for Cross Site Request Forgery. Let us say you are on your Bank Web Site, logged on and paying your bills. While the session is activity, your 5th Grader interrupts you with a Math question. Of course you need to google the answer as you have long forgotten 5th Grade Math Mr. Andy Ruport taught you. You end up on a site that is infected with Malware while you are still logged on to your Bank’s website. The malware on the site could issue a state changing operation such as Fund Transfer on your behalf to your Bank’s website. Since you are already logged on to your Bank Website, there is an active session cookie that get sent on the request to your Bank’s site. So, unbeknownst to you a Fund Transfer request to your Bank on your behalf. This in a nut shell is CSRF Attack.

Refer to the CSRF documentation on OWASP Website for additional information.

The defense for CSRF Attack in a traditional web application is to expect a  CSRF Token on every state changing request that the server validates with the token saved in the Session. Since APIs are supposed to be stateless, there is no CSRF Token that can be maintained across requests in REST API calls. Refer to the CSRF Prevention sheet sheet on OWASP website for additional details. CSRF Guard is a widely used library to implement CSRF Defense in traditional web applications.

The CSRF Defense in REST APIs is to expect a custom header such as X-XSRF-TOKEN by the API. By making the client set a custom header in the request, the attacker can not rely upon traditional CSRF Attach such as auto-submit of a HTML Form as the attacker can not set custom headers via that attack vector. If the attacker were to rely up on  sending an AJAX request using XMLHttpRequest (Level 2) than the CORS protection mechanism supported by all modern browsers would kick in and allow the REST API to accept or deny the request from the attacker controlled site.

This is a simple and elegant CSRF Defense that can be implemented for stateless REST APIs.