Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the cross-domain Ajax is a security concern?

Tags:

ajax

security

xss

Why was it decided that using XMLHTTPRequest for doing XML calls should not do calls across the domain boundary? You can retrieve JavaScript, images, CSS, iframes, and just about any other content I can think of from other domains. Why are the Ajax HTTP requests not allowed to cross the domain boundaries? It seems like an odd limitation to put, considering the only way I could see it being abused, would be if someone were to inject Javascript into the page. However, in this case, you could simply add an img, script, or iframe element to the document to get it to request the third party URL and send it to the server.

[Edit]

Some of the answers point out the following reasons, let's point out the reasons they don't create a major reason to disallow this.

XSRF (Cross Site Request Forgery, also known as CSRF, XSRF)

Your can do XSRF attacks without using this at all. As a general rule, XMLHTTPRequest isn't used at all, simply because it's so hard to make an XMLHTTPRequest in a way that's compatible with all major browsers. It's much easier to just add an img tag to the URL if you want them to load your URL.

Posting to third party site

<script type="text/javascript">   $.post("http://some-bank.com/transfer-money.php",           { amount: "10000", to_account: "xxxx" }) </script> 

Could be accomplished with

<body onload="document.getElementById('InvisbleForm').submit()"     <div style="display:none">         <form id="InvisbleForm" action="http://some-bank.com/transfer-money.php" method="POST">             <input type="hidden" name="amount" value="10000">             <input type="hidden" name="to_account" value="xxxxx">         </form>     </div> </body> 

JPunyon: why would you leave the vulnerability in a new feature

You aren't creating any more insecurities. You are just inconveniencing developers who want to use it in a way for good. Anybody who wants to use this feature for evil (aka awesome) could just use some other method of doing it.

Conclusion

I'm marking the answer from bobince as correct because he pointed out the critical problem. Because XMLHTTPRequest allows you to post, with credentials (cookies) to the destination site, and read the data sent back from the site, along with sending the persons credentials, you could orchestrate some javascript that would submit a series of forms, including confirmation forms, complete with any random keys generated that were put in place to try to prevent a XSRF. In this way, you could browse through the target site, like a bank, and the bank's webserver would be unable to tell that it wasn't just a regular user submitting all these forms.

like image 888
Kibbee Avatar asked Jan 21 '09 20:01

Kibbee


People also ask

Why is cross domain not allowed in AJAX?

Because of Same origin policy. The same-origin policy exists to prevent malicious use of resources. If there were no rules governing cross-domain script access, it would be trivial to wreak all manner of havoc on unsuspecting users.

What are the security issues with AJAX?

AJAX Security: Client Side JavaScript code is visible to a user/hacker. Hacker can use JavaScript code for inferring server-side weaknesses. JavaScript code is downloaded from the server and executed ("eval") at the client and can compromise the client by mal-intended code.

What is cross domain violation AJAX?

Cross-domain policy (or same-origin policy) prevents client JavaScript, loaded from one domain, from accessing or manipulating the properties of a document from another domain. In short, the domain being requested from the client script must match the domain of the current web browser page.

Does AJAX support cross domain?

For a successful cross-domain communication, we need to use dataType “jsonp” in jquery ajax call. JSONP or “JSON with padding” is a complement to the base JSON data format which provides a method to request data from a server in a different domain, something prohibited by typical web browsers.


2 Answers

Why are Ajax HTTP Requests not allowed to cross domain boundaries.

Because AJAX requests are (a) submitted with user credentials, and (b) allow the caller to read the returned data.

It is a combination of these factors that can result in a vulnerability. There are proposals to add a form of cross-domain AJAX that omits user credentials.

you could simply add an img, script, or iframe element to the document

None of those methods allow the caller to read the returned data.

(Except scripts where either it's deliberately set up to allow that, for permitted cross-domain scripting - or where someone's made a terrible cock-up.)

Your can do XSS attacks without using this at all. Posting to third party site

That's not an XSS attack. That's a cross-site request forgery attack (XSRF). There are known ways to solve XSRF attacks, such as including one-time or cryptographic tokens to verify that the submission came deliberately from the user and was not launched from attacker code.

If you allowed cross-domain AJAX you would lose this safeguard. The attacking code could request a page from the banking site, read any authorisation tokens on it, and submit them in a second AJAX request to perform the transfer. And that would be a cross-site scripting attack.

like image 128
bobince Avatar answered Oct 04 '22 13:10

bobince


An important difference between the POST:

<body onload="document.getElementById('InvisbleForm').submit()" ... 

and Ajax is that after doing any POST the browser will replace the page and after doing the Ajax call - not. The result of the POST will be:

  1. Clearly visible to the user.
  2. The attack will be stuck at this point because the response page from my-bank.com will take the control. No bank will implement a one-click-transfer.

The scenario of XSRF, if the cross domain Ajax would be allowed, will look like the following:

  1. User somehow visits www.bad-guy.com.
  2. If there no opened page to my-bank.com in other instance of the browser, the attack is unsuccessful.
  3. But if such page is opened and the user has already entered his user-name/password, this means that there is a cookie for this session in the cache of the browser.
  4. JavaScript code on the page from www.bad-guy.com makes an Ajax call to my-bank.com.
  5. For the browser this is a regular HTTP call, it has to send the my-bank cookies to my-bank.com and it sends them.
  6. Bank processes this request because it cannot distinguish this call from the regular activity of the user.
  7. The fact that JavaScript code can read the response is not important. In the attack case this might be not necessary. What is really important is that the user in front of the computer will have no idea that this interaction takes place. He will look at nice pictures on the www.bad-guy.com page.
  8. JavaScript code makes several other calls to my-bank.com if this is needed.

The gist is that no injection or any page tampering is needed.

A better solution might be to allow the call itself but not to send any cookies. This is very simple solution that does not require any extensive development. In many cases Ajax call goes to unprotected location and not sending cookies will not be a limitation.

The CORS (Cross Origin Resource Sharing) that is under discussion now, among other things, speaks about sending/not sending cookies.

like image 20
Kirill Kobelev Avatar answered Oct 04 '22 14:10

Kirill Kobelev