CORS in embedded javascript - javascript

I'm intending to add security for our Javascript code which gets embedded on other sites - eg: like analytics code.
The user copies 4-5 lines of the code and puts it on his site. The code actually downloads the real script as the next step.
I have been recommended to use CORS instead of the current JSONP calls as I can restrict the domains.
As I understand, the CORS would work only if the html page which will add my scripts needs to add access domains and if I add the access domains for the the js file, it wouldn't work.
Is the CORS for the final js or the html page intending to use my script?
Edit:
Since it's confusing to the users, I have made it more simple.
HTML in domain A adds my script from Domain B like Google analytics. Can I add access-domains: while rendering my JS or should the HTML add the access-domains in the response?

There is a good explanation from wiki for this question:
CORS can be used as a modern alternative to the JSONP pattern. While JSONP supports only the GET request method, CORS also supports other types of HTTP requests. Using CORS enables a web programmer to use regular XMLHttpRequest, which supports better error handling than JSONP. On the other hand, JSONP works on legacy browsers which predate CORS support. CORS is supported by most modern web browsers. Also, while JSONP can cause cross-site scripting (XSS) issues where the external site is compromised, CORS allows websites to manually parse responses to ensure security.
As I understand, the CORS would work only if the html page which will add my scripts needs to add access domains
You can access all domains via:
Access-Control-Allow-Origin: *
Also now CORS has good support.
P.S. IE8-9 has own imlementation by XDomainRequest.

CORS works by having your server output the Access-Control-Allow-Origin header containing the allowed domains. The sites that make ajax requests to your server don't need to do anything special to enable CORS, there is no configuration required. The sites just simply make normal XHR requests and the browser will internally handle the CORS.
You control the CORS access from the header on your server. In CORS, you can also control the HTTP verbs that are allowed, for example POST or GET (Access-Control-Allow-Methods) or the permitted request headers (Access-Control-Allow-Headers).
Note that IE8 doesn't support the CORS XHR, Microsoft decided to create their own CORS implementation with XDomainRequest. So if any of the sites that call your server want to support IE8, they will need to use XDomainRequest instead of XMLHttpRequest. There is no support for CORS in IE7 or eariler - not even XDomainRequest.

Related

How does CORS plugin / --disable-web-security work on browser?

I'm sure I'm not the only one who have used/uses CORS plugins for browsers or --disable-web-security flag while making API calls to external (or even internal) API endpoints. I used this plugin to make Google Maps related API calls. But within the same application, ParseSDK API calls needed no CORS or --disable-web-security flag.
My question is : Why are these endpoints acting differently and how does CORS plugin solve the problem (even though we don't have control over those APIs)?
Thanks in advance.
Well, what that plugin does is highly irresponsible; It actually disables the same origin policy, which enforces that a website on a specific origin can only make requests to that origin.
The same origin policy actually just prevents a website from reading the response of a GET/POST request, the request itself is made, because it's considered safe.
Over time this good security feature became a burden and people used workarounds like JSONP.
So we got a new, standardized way to access foreign origins:
CORS (Cross-Origin Resource Sharing) is a mechanism that allows a web server to specify that another origin is allowed to access its content. This is done with Access-Control-Allow-Origin: example.com which allows example.com to access the response even if the response is from a different origin.
The Access-Control-Allow-Credentials: true would also allow the credentials, which includes cookies and HTTP Basic authentication to be sent within the request.
You can also specify a wildcard for Access-Control-Allow-Origin: *, which allows all websites to access this response. However when you do this you have to specify Access-Control-Allow-Credentials: false, so no credentials are exposed.
This is the only correct way to implement a public accessible AJAX API in the internet.
However this plugin just simply disables the same origin policy completely which is extremely dangerous.
The link you posted (did you read the description?) specifies exactly what the extension does - it adds the Access-Control-Allow-Origin: * header to all responses. This is a CORS header that normally the server sends to notify the browser that you are allowed to make requests from arbitrary origins.
Parse SDK probably supports CORS on their server end.
Just for your information, when most people say CORS they are not referring to a browser extension. They're referring to the web standard called CORS. Documentation below.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Imitating cookies behavior in chrome packed app

I am using REST service, that is not in my control to modify.
The service have verification/login and many "data-retrive" endpoints.
I have been requested to create "Chrome packed app" that will use this REST service.
The limitations I have are:
Can't use sandboxed pages.
Can't use webview.
The problem:
Xhr requests ignore "Set-cookie" headers.
it's impossible to set cookies manually (Like there is no cookie api).
Ideas & research
I googled my way into XHR implementation using "chrome.socket", With no https support, since "chrome.socket" dose not support TLS.
Forge is a "Chrome-js" library that adds TLS support to the "chrome.socket"
Questions
Is there any way to Modify requests and response headers?
Is there any way to combine the XHR implementation using "chrome.socket" with Forge? (I don't really know the protocol or the original XHR implementation)
is it even reasonable to implement fake cookie API to manage the data from the headers?
You should look into using a Cross-Origin Resource Sharing (CORS) request. There is a good introduction here.
In particular, you will need to use withCredentials:
Standard CORS requests do not send or set any cookies by default. In
order to include cookies as part of the request, you need to set the
XMLHttpRequest’s .withCredentials property to true: [...]
Note that you will need the server's cooperation to do this:
In order for this to work, the server must also enable credentials by
setting the Access-Control-Allow-Credentials response header to
“true”.
Since you are always on Chrome, you could use the Fetch API instead of XMLHttpRequest2. In that case you would add the credentials option:
Should you want to make a fetch request with credentials such as
cookies, you should set the credentials of the request to “include”.
Both of these mechanisms will (1) support HTTPS and (2) manage cookies opaquely, i.e. they will not permit you to inspect the cookie data.

ajax response on another domain

I have specific scenario to work with, It will be interesting and helpful to many developers, I have js file and a php file, In js file i code AJAX, using http request that send parameters to php file and get a response.
Now I have 2 domains
on 1st Domain
I have Database, Store some html codes, Can create AJAX to get data from database to a Javascript file.
on 2nd Domain
I want to display HTML codes from the 1st domain database using Javascript or AJAX
Is there any way to do this kind of trick?
You could write a wrapper script on server side to make the call to the second domain and then you just call your script.
You need use CORS technology also look at jsonp
Wikipedia source:
Cross-origin resource sharing (CORS) is a mechanism that allows many resources (e.g., fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain the resource originated from. In particular, JavaScript's AJAX calls can use the XMLHttpRequest mechanism. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request. It is more useful than only allowing same-origin requests, but it is more secure than simply allowing all such cross-origin requests.
Simple Example:
To initiate a cross-origin request, a browser sends the request with an Origin HTTP header. The value of this header is the domain that served the page. For example, suppose a page from http://www.example-social-network.com attempts to access a user's data in online-personal-calendar.com. If the user's browser implements CORS, the following request header would be sent to online-personal-calendar.com:
Origin: http://www.example-social-network.com
If online-personal-calendar.com allows the request, it sends an Access-Control-Allow-Origin (ACAO) header in its response. The value of the header indicates what origin sites are allowed. For example, a response to the previous request could contain the following:
Access-Control-Allow-Origin: http://www.example-social-network.com
If the server does not allow the cross-origin request, the browser will deliver an error to example-social-network.com page instead of the online-personal-calendar.com response.
To allow access from all domains, a server can send the following response header:
Access-Control-Allow-Origin: *
Browser support:
CORS is supported by all browsers based on the following layout engines:
Gecko 1.9.1 (Firefox 3.5, SeaMonkey 2.0, Camino 2.1) and above.
WebKit (Initial revision uncertain, Safari 4 and above, Google Chrome 3 and above, possibly earlier)
MSHTML/Trident 6.0 (Internet Explorer 10) has native support. MSHTML/Trident 4.0 & 5.0 (Internet Explorer 8 & 9) provide partial support via the XDomainRequest object.
Presto-based browsers (Opera) implement CORS as of Opera 12.00 and Opera Mobile 12, but not Opera Mini.
The following browsers are also noteworthy in their lack of CORS support:
1. Camino does not implement CORS in the 2.0.x release series because these versions are based on Gecko 1.9.0.
2. As of version 0.10.2, Arora exposes WebKit's CORS-related APIs, but attempted cross-origin requests will fail.

What are the limitations on AJAX requests in Chrome Apps?

I am planning a Chrome App project where I will be performing numerous AJAX calls. Before settling on Chrome Apps as platform of choice, I would like to have a better understanding of its limitations and advantages regarding AJAX calls compared to web apps. Having conducted some research, I came up with the answers below. Since I have limited experience in this area, I would like to know if my findings are correct and if there are other limitations that should be considered.
1. Origin
Limitations regarding origins are more flexible for Chrome Apps than for web apps: The same-origin policy related to AJAX requests can be relaxed in the app’s manifest by requesting cross-origin permissions. Therefore, there is no need for techniques like Cross-Origin Resource Sharing (CORS) and JSONP (which is in fact prohibited by the Content Security Policy (CSP)).
2. Content
Limitations regarding accessible content are more severe: Chrome Apps can only refer to scripts, stylesheets, images, frames, plugins and fonts within the app, but media resources (video, audio, and associated text tracks) can be loaded from any external resource. The ‘connect-src’ directive is set to allow for loading any URI, so given cross-origin permissions or using CORS, one can make AJAX calls to all hosts and receive text and media type responses. Other content types can be served as blobs. The CSP can not be relaxed.
(A peculiarity I found: As stated, CSP forbids loading several content types, therefore one has to load them as blobs via AJAX requests. As a result of the same-origin policy, this would have to be done via CORS. Most servers don’t have CORS enabled, even if their content is public. Therefore, if Chrome Apps enforced ‘Access-Control-Allow-Origin’ (ACAO) response headers at all times, the CORS approach would fail in a lot of cases.
The solution to this problem is cross-origin permissions: If a permission was given to access a server, even if no appropriate ACAO header is received, the request is let through. But one can rely on CORS alone too: If no cross-origin permission is granted, but the request is made to a server with wildcard ACAO settings, it is also let through.)
Two additional things to note:
Some documentation of Chrome Apps refers to extensions instead of
apps. In these cases I assume that the information provided there is
correct for apps too.
Synchronous XHR requests are disabled.
Unfortunately, you'll just have to test this all out. I've found the Google docs (especially with Chrome apps) to be very lacking and frequently wrong. Going through the docs, it appears they wrote them for extensions, copied all the docs over and then when they encountered a difference, they changed the docs but did not cover everything.
As for accessing external sources, follow these "instructions":
http://developer.chrome.com/apps/app_external.html#external
And if you find an issue, report it BOTH here and https://code.google.com/p/chromium/issues/list

Why is cross domain AJAX prevented *if* you have no intention of evaluating the response as a script?

Let's say I want to use AJAX to retrieve a json file from an untrusted different domain.
I then parse the response as a javascript object without any script evaluation.
(A cookie is not sent with my request.)
I don't understand why the browser prevents me from doing this.
I understand that if I were to evaluate the response as a script then that would be a security issue.
I understand that there are work-arounds to achieve the above.
Is there a reason that my specific scenario should be prevented, or has it just got accidentally caught up in the same-origin dragnet?
Thanks.
(assuming the server does not support CORS)
... you have no intention of evaluating the response as a script?
Firstly, browser security has no way of determining what you intend to do.
Second, the same source / origin restrictions are designed prevent other things as well: e.g. see
http://blogs.msdn.com/b/ieinternals/archive/2009/08/28/explaining-same-origin-policy-part-1-deny-read.aspx
Cross-domain AJAX is possible, but the remote server needs to support CORS and there may be certain header restrictions.
JSONP is not necessary for most applications. If the remote server does not support CORS, then you're stuck with the same-origin garbage and you'll have to use JSONP.
Note:
Older browsers don't support CORS. You may want to use jQuery or a similar framework (I've had trouble with Mootools and cross-domain AJAX because I couldn't figure out how to remove some of the default headers. jQuery worked out of the box for me on my set-up.

Categories