Cross-Origin resource sharing and file:// - javascript

I am writing an HTML5 application that is gathering data from a few different sources using JSONP. Anything I'm doing with a GET works perfectly. I'm now trying to POST data, and I've run into an interesting snag. I need to POST data from my application to another, where my application is running from a local machine. I am trying to write a cross-platform capable mobile application (think Pulse/Flipboard), so the code will always be running from a local source. My thought process was as follows:
Use JSONP - JSONP does not allow for posting, it just doesn't work that way (Post data to JsonP)
Rely on CORS - Since the request is coming from a local source using file://, the origin header is null. This causes the request to fail (XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin)
Use another server to bounce the request off of - this would be expensive
All of the browsers I'm targeting are webkit based (iPad, Playbook, Android), so I'm wondering if there are any creaks in the same origin policy code that I can sneak through? Maybe something using iframe or postMessage?

As it would turn out, the easiest way to do this is to post to the target url inside of an iframe. Same origin policy on most browsers allows you to perform an HTTP POST from one domain to another unrelated domain. I solved the problem by adding an iframe to my page, initially set to a local bootstrapping page. Since that page was loaded from the same domain, I am able to control it via script. I used that to post the form to my target site, and polled the results to determine if my call was successful. It's not elegant, but it works.

This Javascript library can almost certainly help you:
http://easyxdm.net/
easyXDM is a Javascript library that
enables you as a developer to easily
work around the limitation set in
place by the Same Origin Policy, in
turn making it easy to communicate and
expose javascript API’s across domain
boundaries.
..
At the core easyXDM provides a
transport stack capable of passing
string based messages between two
windows, a consumer (the main
document) and a provider (a document
included using an iframe). It does
this by using one of several available
techniques, always selecting the most
efficient one for the current browser.
For all implementations the transport
stack offers bi-directionality,
reliability, queueing and
sender-verification.

Related

How can I override the Origin header in Chrome when connecting to a WebSocket?

I am trying to connect to an external web socket server, which is not run by myself. I would like to connect to it from a localhost javascript file, therefore the origin header has null value.
I understand that this is a measure against cross-site forgery. However, since I am on localhost, I should be able to fake this, by getting Chrome to send a custom Origin header.
Is it possible? (if I need an extension, that is fine)
If not, what is my best option to achieve the above? Thank you.
Web pages cannot change the Origin header, but extensions can modify the request headers via the chrome.webRequest API. But ws:// and wss:// are not supported by this API, so this doesn't help unless the server also supports other means of communication via http(s) (e.g. long-polling).
There is still a solution though: Simply load a (known) web page at the desired origin in an iframe (e.g. https://example.com/favicon.ico or https://example.com/robots.txt) and use a content script to open the WebSocket from there.
The Origin header is one of the headers that are set automatically by the user agent (as part of the browser implementation), and cannot be altered programatically or through extensions. This makes sense because web service providers cannot allow random connections from localhosts.
You can connect to an external WebSocket only if you do it from a host explicitly accepted by the web service provider. Many headers cannot be trusted (because they can be overridden), but this is not the case with Origin as it offers security not only for users, but also for service providers against unwanted connections.
As far as I know this will not be possible, it would break the security guards against CSRF in Chrome.
If you were able to do that the whole concept of XHR would fall apart.
Here is an Extension you can use to manipulate header on the fly, but so far I have not been able to get it to manipulate socket headers.
Look here if you want to read more about this.
But this doesn't stop you from implementing your own client (in place of chrome) where you can literally send whatever headers you want, not sure if this helps you, sorry.
It depends how you want to use your chrome browser. Since you mention localhost I assume you develop and will use this for some kind of scraping. I suggest that you explore Chrome DevTools Protocol which will render (almost) any kind of protection useless because you use a real browser. CORS, Origin, Cookie or any arbitrary header value will be under your control, and you can send a custom header for xhr/websocket request(s). If you want to manipulate in a more advanced way you can use Network.continueInterceptedRequest. You might only want to start chrome using parameters like "--disable-web-security, --disable-xss-auditor, --disable-client-side-phishing-detection, --allow-insecure-localhost" more about such options at peter.sh. However, the last option require a plugin in order to spoof origin header so I recommend the first option.

$http gives "not allowed by Access-Control-Allow-Origin" error in Chrome [duplicate]

This question already has answers here:
Ways to circumvent the same-origin policy
(8 answers)
Closed 9 years ago.
Trying to access http://www.kawa.net/works/ajax/romanize/romanize.cgi?q=%ED%96%88%EB%8B%A4?&mode=hangulis I only get the error "not allowed by Access-Control-Allow-Origin." I tried Googling this problem and found 2 suggestions, 1 saying I should start Chrome with --allow-file-access-from-files and one saying I should run the page/script on a WAAMP server. Neither of these worked. From what I gather this is due to security reasons. I'm thinking about simply making the $http request go to my server instead where I will have a PHP file that contacts the external URL instead. I guess my question is: is it necessary to do that or is there any way I can do it from the client script?
In an attempt to secure them from cross site scripting attacks, browsers have a built in security feature that prevents javascript from making HTTP (a.k.a AJAX) requests to URLs that are not within the same domain as the originally requested HTML page.
[In particular Chrome restricts any HTTP request when the original HTML file was received from the local file system (i.e. file:///...). As you state you can turn this off with the --allow-file-access-from-files option, or fix it by always loading your page from a web server rather than directly from the file system.]
This turns out to be rather restrictive, since there are a number of valid cases where your javascript application would want to access a web service provided by a 3rd party, which is located on a different domain. In your case you want to access a service that will romanize Korean Hangul characters.
So there are a number of ways around this restriction:
Proxy On Your Servery
The first is to provide a proxy service on your own server that will pass on the request to the 3rd party service and then return it to the browser. The browser is making a request to the same server (i.e. domain) from where it got the original HTML and so is happy.
JSONP
The second is to use a hack, such as JSONP (http://en.wikipedia.org/wiki/JSONP), which involves dynamically adding a new script tag to your HTML that will load up a new JavaScript file and execute it. You have to configure the server to wrap up the data you requested in a call to a function that is provided by your application in the browser to unwrap the data and use it. This is supported by AngularJS $http service using the .jsonp method: http://docs.angularjs.org/api/ng.$http#jsonp. Take a look at the example at the bottom of the page for more information.
CORS
The final, and most sophisticated method is to take advantage of a standard called Cross Origin Resource Sharing (CORS) : http://en.wikipedia.org/wiki/Cross-origin_resource_sharing. This is a standard provided in most browsers now where the browser is able to negotiate with a server hosting a resource on a different domain to agree that certain data can be returned. It needs no changes in the client application, and as such is fully supported for $http, but it requires you to set up the server to be able to respond appropriately. I guess that the service you are referring to is not supporting this. By the way, when CORS is in operation, you will see a number of extra OPTION requests being sent to the server. This is part of the negotiation mechanism and is perfectly normal.

javascript which makes cross domain GET requests and assigns it to a variable

for quite a long time i am looking for a javascript code which can make cross domain GET requests..
i want to make a javascript which makes a GET request to google and fetches the page source and assigns it to a variable..
note:the get requests must be generated from the clients computer and to a different server(eg:google)
Not possible due to the same origin policy which restricts AJAX and iFrames.
However, afaik Google offers a very own AJAX API to fetch search results, thats maybe enough for your needs.
But unless the Google servers don't allow for cross-domain calls (which I don't believe) there is no way in fetching data via a pure client-side AJAX connection.
Disclaimer: it might be possible in some browsers by changing some core settings

How can we use JavaScript for cross-domain getting of a web page Without the use of XMLHttpRequest? Is there a plug-in that could do this?

using JavaScript, it is much needed to get some pages from the web using without actually moving from the current page and hidden from the user's eyes.
To request a web page without showing it to the user, it is easy to use XMLHttpRequest but it has its own limitations most importantly it does not retrieve cross-domain pages very well. For security reasons the browsers (Mozilla FireFox 3.6+ in my case) retrieve a header from the target site and if the referrer's location is allowed access in that header, only then will the browser continue getting the target web page and JavaScript can only then parse the retrieved info.
This causes the XMLHttpRequest to work with some pages and not work with others if you are trying to access cross-domain pages. Of course it works well if you need to retrieve the information from the same location as the referrer page where the XMLHttpRequest is located.
This is a big problem, when security is not really no 1 priority. For example, imagine writing a script for retrieving live data from a statistics-producing web site or imagine a bot that needs to retrieve data from an online gaming web-site.
Now, how can JavaScript be used to get pages from other domains (cross-domain reference)?
I thought maybe we could find a plug-in that does the job (of course after installation upon user's permission) and then use its properties by JS and eliminate the need for XMLHttpRequest. Do you know any such plug-in or another roundabout for this problem? (ie get cross-domain data by JS without XMLHttpRequest) of course we cannot use XMLHttpRequest as we don't have any control over the target page headers and we obviously want to hide the whole process from the user
You’ll find that it’s the priority that the target site puts on their own security that is most important. If they're unconcerned about JavaScript on other sites accessing their site, they can set the HTTP Access Control headers for cross-domain XMLHTTPRequest, provide a crossdomain.xml file for Flash, provide a JSONP API, or provide some hooks for iframe monitoring.
The second solution is to make the requests to a server on your domain which proxies the request to the target site. In certain circumstances you may be able to use a third party server which supports cross-domain or JSONP requests, like Yahoo! Pipes.
If neither of these is feasible, you'll need to convince the user to allow you to run your own code on their PC. This could be via a signed Java applet which requests special permissions, or your own custom browser plugins or extensions.
There are several ways including using JSONP with XMLHttpRequest, using Flash and using iframes.
Here is some information on this subject. http://snook.ca/archives/javascript/cross_domain_aj

Suppressing browser's authentication dialog

I apologize that there is a similar question already but I'd like to ask it more broadly.
Is there any way at all to determine on the client side of a web application if requesting a resource will return a 401 status code and cause the browser to display an ugly authentication dialog?
Or, is there any way at all to load an mp3 audio resource in flash which fails invisibly in the case of a 401 status code rather than letting the browser show an ugly dialog?
The Adobe Air run-time will suppress the authentication if I set the "authenticate" property of the URLRequest object but this property is not in the Flash run-time. Any solution which works on the client will do. An XMLHttpRequest is not likely to work as the resources in questions will be at different domains.
It is important to fail invisibly because the application will have a list of many audio resources to try and it makes no sense to bother the user to try and authenticate for one when there are many others available. It is important that the solution work on the client because the mp3's in question come from various servers outside my control.
I'm having the same problem with the twitter api - any protected user requires the client to authenticate.
The only solution that I could come up with was to load the pages serverside and return a list of the urls with their http response code.
"Is there any way at all to determine on the client side of a web application if requesting a resource will return a 401 status code and cause the browser to display an ugly authentication dialog?"
No, not in general. The 401 response is the only standard way for the server to indicate that authentication is necessary.
Just wrap your access to the resource that might potentially require authentication to an Ajax call. You can catch the response code, and use javascript to do whatever you want (ie. play that sound). If the response code is however alright, then use javascript to forward user to the resource.
Most likely this approach will generate slightly more load on server (you might have to resort to loading the same resource several times in some circumstances), but it should work. Any good tutorial about how to use XMLHttpRequest should contain all you need. Take a look at for instance http://www.xul.fr/en-xml-ajax.html
If you are using URLRequest to get the files, then you are running across more than just elegant error handling, you are running into a fundamental difference in the Flash and AIR run-times.
If using the URLRequest object to retrieve files you are going to get a security error from Flash on every request to every server that has not set a policy file to allow these sort of requests. AIR allows these requests since it basically IS the client. This makes sense since it's the difference between installing an application and visiting a web page.
I hate to provide the non-answer, but if you can't make a server-side call, and you are hitting a range of "not-known" servers, it's going to be a tough road to hoe.
But maybe I misunderstand, are you just trying to Link to the files and prevent the user from getting bad links, or are you trying to actually load the files?

Categories