Wednesday, May 28, 2008

XHR, CSRF and bypassing the browser same origin policy

I did a presentation on CSRF for my local OWASP chapter and an interesting question come out about exploiting a CSRF vulnerability while using XMLHttpRequests (these are very popular wih Ajax nowdays..) CSRF vulnerabilities exploit the trust that a site has on the browser. In the case of an authenticated session, since the browser does not resend a NEW SessionID to the application as a proof that each HTTP request is authenticated it allow for riding the session with an interleaved malicious HTTP request (I like this term better actually because you are really riding an authenticated session..).

If I social engineer (phish) a victim forcing him to select a web page (via webmial for example) that has a malicious HTML tag such as iframe with an embedded GET request and if such request is issued (by the victim web page selection) when an authenticated session with the same application is still valid, then such malicious request will processed by the application. Attack of this nature can eventually force a business transaction such as money bank transfer, denial of service via forced logout, modification of shopping cart credentials to force a purchase with a price and address at the choice of a malicious user.

The main root causes of CSRF on the client is the lack of enforcement of the same origin policy. Such policy prevent two different documents loaded on the browser and one potentially being malicious to access each other via javascript. The same origin policy will check that such javascript invocation comes from two different sources and it will deny it. The problem is that such same origin policy does not work for HTML tags: an hacker can embed an URL from untrusted source/domain in one of the documents serve such document to the victim and the request will still be issued to the site and being authenticated by the application. Contrary to HTML tags, in the case of issuing asynch requests via XmlHttpRequest (XHR) the same origin policy is enforced on the browser and in-theory a CSRF attack will be mitigated by the browser control.
The reality is that if malware is present on the client (such as with XSS exploit for example), then you can potentially override this control, simply because XHR relies on client javascript. In other cases if the control is invoked via a flash the same origin policy can be actually disabled to this vulnerability as a configuration management issue.

Here are the facts in the details :
1) XMLHttpRequest has a same origin policy enforced in both IE and Mozilla
2) Because of the same origin policy you cannot access, a document/script loaded from one site of origin from a site from a different origin
3) XMLHttpRequest rely on javascript to issue POSTs such as:

var post_data = 'name=value';
var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");"POST", 'http://url/path/file.ext', true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4)

4)Since XHR rely on javascript, you can have malware (like Samy webworm that exploits both XSS and CSRF) installed on the client that can overwrite the javascript function by overriding the constructor XMLHttpRequest() { } By doing so the hacker is bypassing the XHR call and will disables the same origin functionality enforced on XHR

5)The same origin policy can also be bypassed with a flash Adobe/Macromedia Flash to issue XHR because cross domain is permitted depending on a rule set in “crossdomain.xml” file present in the root of the target webserver.

So basically like everything else in security, there is no 100% mitigation of the risk. In the case of XHR CSRF browser controls can also be bypassed despite the same origin policy on the browser. The golden rule for security is to rely on multi layer security, XHR with same origin policy but also unique token for each URL and tied to the user session like you can do by using OWASP Guard. To remediate CSRF vulnerabilities every HTTP request (not just the one that you login into it) that can potentially exploited for unauthorized transactions (i.e. HTTP POST of confidential data, high risk transactions) need to be authenticated by issuing a new token/sessionID or event by requiring a PIN


No comments: