Cross Site XMLHttpRequest: Difference between revisions
No edit summary |
No edit summary |
||
Line 26: | Line 26: | ||
In fact we wouldn't even need to create a dummy document. We could simply set up a custom sink that just checks the incoming processing instructions until the first element. This could even be implemented by the same object as the nsIRequestObserver wrapper. | In fact we wouldn't even need to create a dummy document. We could simply set up a custom sink that just checks the incoming processing instructions until the first element. This could even be implemented by the same object as the nsIRequestObserver wrapper. | ||
=== Issues === | === Issues === |
Revision as of 04:26, 24 January 2007
Cross-Site XMLHttpRequest allows a web page to read information from other web servers using norm XMLHttpRequest. In the past this has not been permitted since the other server may be sitting inside a corporate firewall or may be a server where the user is logged in.
To solve this problem it is suggested that the accessed server can signal back to the browser that it is ok for other sites to access certain pages on the server. Firefox checks for this and only returns the response to the page if the server explicitly allows it. Otherwise the browser will throw away the response from the server and throw an exception.
Details
There are currently two draft specs from w3c for how this should work. The signaling for when a document is accessible is spec'ed in the access-control draft spec [1]. This states that the site can insert <?access-control?> processing instructions into XML files that says which sites can access the file. It also allows for http-headers to be added to allow access to be controlled to any file type.
The PI contains lists of URL patterns that describe which URLs can access the file. These patterns can contain wildcards, but follow strict parsing rules rather than being general URLs.
Additionally [2] is a draft spec for how XMLHttpRequest should interact with the access-control spec. This spec describes some headers that should be included when making a cross site request. (Though I personally wonder if this part should be moved into the access-control spec.) It also describes how to deal with http methods other than GET and POST.
Suggested Implementation
A goal of the implementation is that it should be reusable for other things than XMLHttpRequest. For example document.load should be able to do the same cross-site loads with the same restrictions. As should XSLT and XBL.
One tricky aspect is that the access control information can show up in two places. Both as HTTP headers, and as PIs inside XML files. Because of this it is suggested that the implementation has two parts:
- An nsIRequestObserver that checked the headers during onStartRequest. The observer is given the uri of the requesting page when created and if the page doesn't have access throws an exception thereby aborting the request. The observer act as a wrapper and forwards all calls to the existing nsIRequestObserver implementation (in the case of XMLHttpRequest the nsXMLHttpRequest class).
- A flag in nsExpatDriver that makes the driver not send any notifications to the sink until either it has passed the matched an access control PI, or it has reached the first element without finding a matching PI. If access should be denied the sink is canceled and we need to signal back to the XMLHttpRequest that loading failed.
Unfortunately gecko architecture forces us to create a document before we create an nsExpatDriver. In fact, I'm not sure there is a way to even know that an nsExpatDriver will be created other than by calling StartDocumentLoad on the document. We could possibly set up a dummy document until we get word from the nsExpatDriver that the access checks were successful and if they are set up a real document and restart the load.
If we set up a dummy document it might be possible to do all this inside the nsIRequestObserver wrapper if we expand it into an nsIStreamListener. It would set up a dummy document and while streaming data into its streamlistener also copy all received data. If access control checks pass we could simply call into the outer listener and stream all copied data to it.
In fact we wouldn't even need to create a dummy document. We could simply set up a custom sink that just checks the incoming processing instructions until the first element. This could even be implemented by the same object as the nsIRequestObserver wrapper.
Issues
- If the check in onStartRequest fails, should we call the wrapping onStartRequest? The nsIRequestObserver interfaces says we must, but there is no way to indicate that the request is aborted. Or will canceling the request indicate that?
- If we set up the dummy document inside the nsIRequestObserver wrapper, will it matter that we call onStartRequest on the outer listener not until we've passed the access checks? Does data disappear from the channel once data start coming in? Maybe we could call onStartRequest even though we don't know that the load is going to succeed? This would allow things like mimetype overrides to XML to work seamlessly I think. We'd have to watch out for this causing onreadystatechange requests to be fired.
Security worries
- The first thing that worries me is that you can make POST submissions to any url and include XML data as payload. It is already possible to make POST submissions to any url, but the only possible payload is plain/text encoded form data or multipart/mixed encoded files and form data. With Cross-Site XMLHttpRequest it would be possible to send XML data. In particular there is worry that this would make it possible to do SOAP requests to any server. Note that while the page would be unable to access the data returned by the SOAP request, that isn't necessary if the request itself is "transfer all users money to account 12345-67"
- Should we try to follow these specs even when accessing files on the same domain? From the sites point of view they can't rely on that anyway since all browsers don't support the access-control spec (and old versions never will).
- What are the security implications of setting up the "real" document before knowing if access checks will succeed or not. We could easily make sure the page doesn't get access to the document, but there might be other worries.
- We have to make sure to not notify the onreadystatechange listener or any other listeners until we've done all access control checks. Otherwise it would be possible to check for the availability of files on other servers though you couldn't actually read the content.
- We have to make sure to not put data in .responseText until we've passed access control checks even for XML files.