Monday, November 28, 2011

CSRF with JSON – leveraging XHR and CORS

Same Origin Policy (SOP) dictates cross domain calls and allows establishment of cross domain connections. SOP bypasses allow CSRF attack vector, an attacker can inject a payload on cross domain page that initiate a request without consent or knowledge of the target user. HTML 5 is having one more policy in place called CORS (Cross Origin Resource Sharing). CORS is a “response blind” technique and controlled by extra added HTTP header “orgin” and their variants but it allows request to hit the target in one way direction. Hence, it is possible to do one-way CSRF. It is possible to initiate CSRF vector using XHR-Level 2 on HTML 5 pages and can prove really lethal attack vector. XHR establishes a stealth connection and remains much hidden, XHR connection can be set using “withCredentials” as true along with POST method. It allows cookie to replay and helps in crafting successful CSRF scenario or session riding. Interestingly HTML 5 along with CORS allows performing file upload CSRF as well. It is possible to craft a JavaScript using XHR and inject JSON payload as cross domain. If server side code on JSON library is not validating the “Content-Type” then it will process the request and allows successful CSRF.
For example,

Here is a script which will do CSRF on cross domain.

Here, we have “Content-Type” as “text-plain” and no new extra header added so CORS will not initiate OPTIONS to check rules on the server side and directly make POST request. At  the same time we have kept credential to “true” so cookie will replay.

On the wire we can see following request.

As you can see cookie is replayed and JSON POST has been initiated. We get following response back from application.

Application processed the request and sent JSON back. It is clear case of CSRF. This can be applied to other streams as well.