How do I set ACAS and CORS request? - javascript

So I have been developing a webpage the would give random quotes whenever a user clicks on a button by calling an API.
Please refer to my previous question for more information Not able to get values (quotes) from the API using jquery
I was told that the reason I couldn't get the response from the API is because my ACAS(Access-control-Allow-Origin) is not set properly in my server and I have to debug it.
Now that I don't much about ACAS or CORS. I have some questions. SO here they are:
1. What exactly is ACAS and how is it related to CORS?
2. How do I debug my page and set the ACAS?
3. Does that have to do anything with my jQuery? Or should I configure only my browser.

You can find many documents on the internet
,so I'll just briefly talk about CORS.
When you're sending request to different domain
for example from a.com to b.com, or localhost:8080 to a.com......
your're making a cross-origin HTTP request ,
sometime this is not allowed, for example Ajax (as you're doing) requests.
Because XhttpRequest, Fetch (both are Ajax API) follow same-origin policy, which means by default you can only make requests form the same domain, ex: from site.com to site.com/users.
The reason they follow the same-origin policy is to prevent CSRF attack (Cross-site request forgery).
1.So basically you cannot get the result of cross site Ajax request, it will block by browser because of the security issue, unless the response header Access-control-Allow-Origin is set to allow client's site to send cross site ajax request. ex: Access-control-Allow-Origin:*allow all sites form different domain; Access-control-Allow-Origin:www.b.comonly allow www.b.com domain.
2.Take Chrome for example If the cross site request's result is blocked, it will show on browser's console:
You need to set the response header in your server, for example I set Access-control-Allow-Origin:*, then in browser's "network" console you can see the header is set, and now I can get the Ajax result.
I think nothing should do at client side, all is at server side.

Refer to this post as it makes this clear
Note also that there are some techniques frequently used in order to bypass CORS like setting up a proxy which acts as a relay for your request or using JSONP instead of JSON.

Related

how to secure my ajax request which comes from multiple domain?

I want to accept only limit domain requests such as i want to accept all request which comes from www.abc.com and www.xyz.com all other request should be denied . I can't be use token process from server side because multiple domain using my javascript code so here we can't think about server side token and HTTP_ADDR can be manipulate from javascript. Please suggest how to validate it which is reliable?
XMLHttpRequest will insert an Origin header into the request which tells you the site that the request came from.
Use that to populate the Access-Control-Allow-Origin header.
(This, obviously, provides no protection against non-Ajax requests).
It appears that you are trying to prevent Cross Site Request Forgery (CSRF) rather than preventing actors from creating arbitrary cURL requests to your site in order to retrieve data. For this purpose, I recommend the following approach.
For "safe" methods you could check that the Origin header matches your whitelist, and if so you output the Access-Control-Allow-Origin header to match. This is an implementation of CORS.
For "unsafe" methods you could set and check a header such as X-Requested-With is present. It is harder to secure unsafe methods using Origin because old browsers do not send the header, and some new browsers do not send the header for same origin requests.
The above approach only works for AJAX, and not for normal form GET or POSTs or cross domain resource requests.

Usefulness of Same Origin Policy with CORS

I have read some articles on Same Origin Policy and CORS and still doesn't understand well the security that it brings to the user.
The Same Origin Policy gives a true valuable security, preventing a site from an origin from accessing some webpage content on another website. Thus preventing the threat of having the content of a iframe accessed by the script of the container, possibly faked/phishing website.
But here comes AJAX and CORS. CORS gives the ability for the server to control which origins can access it. But, at the end, it is the browser which stops the request if not allowed, after headers handcheck.
So, imagine you get some malicious website myphishing.com. You want to show information from another trusted website mybank.com through AJAX request to this site. This one is protected by well configured CORS headers only allowing request from mybank.com origin. What if, me author of myphising.com, relay all requests to mybank.com by a proxy that alter headers in both request and response way to fake client browser and bank server? It seems one can change the origin header in the request for a mybank.com one, and change the CORS response headers to make the browser think myphishing.com is allowed to make the request. Headers handcheck passed, you can then send the request and get the response with similar headers substitution tricks.
Perhaps I'm totally misleaded, but I would be very pleased if someone could show me where I have misunderstand the whole thing.
Possible duplicate but I didn't find my answer here: What is the threat model for the same origin policy?.
What if, me author of myphising.com, relay all requests to mybank.com by a proxy that alter headers in both request and response way to fake client browser and bank server?
You could do that anyway, CORS or no CORS.
If the request is coming from your proxy, however, then it has no way to know what credentials the browser would have sent to the server if the request was coming from the browser.

cross-origin xhr and same-origin-policy

This is a concept that I thought I understood, but recently found out I had all wrong. I've looked all around the internet and find plenty of examples of small details and code snippets, but I still lack an understanding of what it prevents and why it prevents it and for whose sake. So this is more of a request for a high-level explanation than a question.
Anyways, here's what I THINK I understand about it:
Let's say I have domain A.com and domain B.com. Each on their own apache servers with their own IP addresses.
I load an html file from domain A.com into a browser. The browser executes a POST XMLHttpRequest to B.com/doStuff.php, which fails because the same-domain-policy was set.
So:
Who's same-domain-policy is relevant? I think the answer is B.com/doStuff.php's... right? So when A sends the request, B checks the request headers for an origin and says "whoops, different domain, won't listen to you". Or does A send the request, B responds with headers that specify "same-domain-policy", and then the browser checks that because same-domain-policy was specified, and the domain from the headers of the A request don't match the one from the B request the BROWSER refuses to send out the xhr?
If that's the case, it seems that the point of not allowing cross-origin-requests is because "I don't want anyone other than me accessing my API". Is that all? Because wouldn't you want to solve that with some kind of authentication instead? Couldn't someone just construct an HTTP request with a fake origin header (simply lie)?
Or is this somehow supposed to protect the user? If that's the case, how is preventing them from calling your API ever going to protect anyone?
I'm so confused...
Who's same-domain-policy is relevant?
The server receiving the request decides.
... the BROWSER refuses to send out the xhr?
No, the server refuses to respond. To be more exact, in modern browsers it is done by preflighted requests. It means that for each cross-origin request, first an OPTIONS request is sent automatically by the browser whose headers are the exact same as the intended request will have but with no request body. The server responds also with headers only. Access-Control headers in the response will let the client browser know whether the request would be fulfilled according to the server's policies. In a sense the browser is preventing the request, but only because it already exchanged a request/response pair with the server and knows that there would be no point to attempt the request. If you forge a request in such a case, the server will still deny serving it.
The idea is that you don't want to access server b from server A via Javascript. If you're interacting with an API, you would use javascript to make a call to your own server's backend code, which would then make a call to the other server.

Jquery: $.getJSON with different url port

I am trying to use $.getJSON with a local app calling another local app on a different port.
For example my app is running on localhost:3000, but I want to make a $.getJSON call to another app running on localhost:3001, in firebug it returns red with a 200 response, but with no data in the response. Is there a way to do this? I tried this....
$.getJSON('http://localhost:3001/dashboard/widgets/marketing_efficiency_gauge.json',
{ key: 'value' }, function(data){
alert(data)
});
Edit: for clarity there are two rails apps involved one on localhost:3000 another on localhost:3001
Second edit: here is the json response for localhost:3001 when I hit it with a browser (say firefox) https://gist.github.com/willfults/7665299
The Same Origin Policy prevents JavaScript scripts from making HTTP requests to different domains. For the purposes of SOP, a URL with the same hostname but different ports (as is the case here) is still considered to be a different domain, and hence requests are not permitted.
What typically happens in such cases is that the browser actually does make the request over the network, but drops the response and sends an error result to the JavaScript.
To fix this, you'll need to implement Cross-Origin Resource Sharing on the localhost:3001 service. In a nutshell, this entails adding a Access-Control-Allow-Origin header to responses listing the domains which are permitted to make cross-domain requests to the service. That is, in this case adding a Access-Control-Allow-Origin: localhost:3000 header to the response from the localhost:3001 service should allow things to work as you expect.
Incidentally, this is why the browser makes the request but drops the result: it needs to request the headers from the server in order to determine whether the JavaScript is allowed to make the request or not (i.e. it needs to check if there's a Access-Control-Allow-Origin header in the response). Why a HEAD request isn't sufficient, I don't know.
The other alternative is to use JSONP. This is potentially simpler to implement on the server side, but has the disadvantages of only working for GET requests, and requiring slightly trickier coding on the client side.

Calling HTTPS from HTTP through AJAX for login

I know its violates the Same origin policy, and that is why it is not possible through simple ajax request. I could use JSONP. But using JSONP for login doesn't sound secure ( no post only get ).
So is there a more secure way of implementing login into https through ajax ?
Not only does it violate the same origin policy, but since the page you are calling from is insecure it has the potential to be interfered with and leak all the data you are trying to keep secure.
Use HTTPS for the entire process.
Better yet, keep using HTTPS while people are logged in, otherwise you will have the Firesheep problem.
As we've discussed in the comments below, this is what Facebook does for their registration page, although there are some vulnerabilities to this method. While it won't appear secure to the user (no lock icon), the actual request is done over HTTPS. If you controlled the entirety of the receiving page, there would be nothing less secure about doing a JSONP request over GET. However, a man-in-the-middle attack could modify the receiving page on load, and cause the returned credentials to be sent to an attacker.
On the plus side though, no one that's just sniffing packets is going to be able to get the credentials: an attack would have to be fairly targeted.
Regarding cookies, technically, JSONP could "return" cookies; you'd just return name-value pairs of the cookies you wanted to set, and have a function on the receiving page set them.
But unless the browser treats <script>s differently, and it might, you should be able to set a cookie in the normal way using the Response Headers of your JSONP response.

Categories