Recently, Dojo has the opportunity to make cross site POST requests, i.e. sending POST requests to other sites with other domain names. This event went unnoticed in our community of JavaScript developers. At least no one said a word about it. And in vain ...
At one fine moment
needed the ability to make cross-site POST requests. Naturally understanding that at the moment browser security prohibits cross-site AJAX, the option to use Flash-AJAX bundle was chosen. But all the same, I personally like “clean” JavaScript solutions. Therefore, until the end we are still not satisfied. Recently in the morning being in the alpha state of sleep, I dreamed of the principle on the basis of which, XSS POST can be implemented using only JavaScript. The essence of XSS POST implementation is based on the data storage features in the window.name property. Thoughts came through the recent series of articles on the Internet about window.name. Having rummaged in Google, at once there was already ready implementation. (Looks like a dream, not only me). Dojo as always ahead of the rest of the planet
www.sitepen.com/blog/2008/07/22/windowname-transport . Well done.
How it works
The principle of operation is described in some detail by the previously mentioned link. In a nutshell: if you change the window.name property, it remains changed while the browser (tab tab) is open. If you change a property on one site, you can then read it on another. Those. when moving from site to site, the browser does not clear window.name. Moreover, this window.name value storage mechanism works in all browsers. XSS POST transport uses this great feature. In other words: when sending data to another server, the following happens:
- load the page from another site / domain
- this page leaves its mark in window.name
- back to your website / domain
- read left trace from window.name
In addition, to send a POST request, use the trick with the target attribute of the form element (principle of the AJAX Uploader, Gmail Uploader files).
The response from the site to which the request is sent should be in the following format:
<script>
window.name = ' , ';
</script>
Accordingly, this approach does not allow taking data without the knowledge of the owner of another site, because the answer must be formed in a specific format. This circumstance keeps safety and protects from XSS scrabing. Those. in fact, this is somewhat similar to the mechanism for resolving cross-domain requests (cross-domain.xml) in Flash.
')
In more detail
- An iframe is created and the handler is hung on the onload event.
- If you just need a GET request, then the iframe in the src attribute is set to the URL address of the resource. If a POST request is needed, a form is dynamically created. The address of the resource is already indicated in the action attribute of the form object, and the parameters are passed in the input elements (name = parameter name, value = parameter value). To associate an iframe with a form (form), it has the same identifier (id attribute) as iframe. After the form is generated, the form form method is simply called. Request made.
- The callback function specified in the iframe works after the data has loaded. In our case, a
<script>window.name=''</script>
structure is loaded and the data falls into the name property of the contentWindow object. The task handler is to retrieve this data. And if you make an appeal to iframe.contentWindow.name, it will be denied access. To get around this problem you need to return to your domain, this is done by changing the value of the attribute of the location of the contentWindow object. For example, you can specify an address on an empty blank.html from your own domain or simply write “about: blank” (iframe.contentWindow.location = 'about: blank'). After that, you can read the data from the name attribute.
Regarding the current implementation from Dojo
After analyzing their development
dojox.io.windowName.js we found a number of significant flaws:
- Strong dependence on the core, which weighs quite "sour."
- The need for a "resources / blank.html" file.
In addition:
- we didn’t like the code, our subjective opinion is a dirty code.
- for FireFox, additional “gestures” are applied (comment in the source code regarding this: FF2 allows unsafe sibling frame modification) - to be honest, we didn’t understand what exactly ...
We wanted to improve the current state of XSS POST and, accordingly, wrote our implementation, which is much smaller in volume, self-contained and not tied to any of the libraries, the code is cleaner and more optimal. Compare and judge for yourself:
Call example:
SRAX.XSS.post( 'http://okarta.ru/scripts/post-xhr.php' , 'a=a1&b=b2' , function (text){
alert(text)
})
XSS POST in our implementation will be further refined and developed, respectively, will acquire more methods and parameters. Who is interested, can always download a newer version.
As always, there is a common drawback: when using an iframe to transfer data, a history appears in the browser, i.e. Activates the back button. Can anyone know how to insert an iframe without triggering a story? It was great to eliminate this flaw.
Why do you need it
For a long time there are mechanisms for XSS GET data request. To this day, they are often enough to solve more problems. But still, sometimes there are times when the limitations of GET requests do not allow to solve the necessary problem qualitatively. For example, the Google AJAX Language API is implemented on XSS GET requests and has a limit on the number of characters to be translated per request — 500 characters. Now with XSS POST, this restriction can be safely removed. There are other cases where XSS POST is vital. XSS POST transport even very useful to competent specialists.
The author of the article is Ruslan Sinitsky, the co-author is KM Aleksandrov. ( M007 )