Access-Control-Allow-Origin and handling from localhost - javascript

So, in my React app, I am making some endpoint calls to different servers and I also have withCredentials set to true, since I pass some token/cookie along with all the requests.
Now, how can I make this work on localhost seamlessly? Since I have withCredentials to true, the
Access-Control-Allow-Origin needs to have specific origin and cannot have * (so if host is localhost:3000, it is not allowed and I get CORS error)
Any ideas on making this work both for local testing and for env deployments?

Create a list of origins that are allowed to access each environment. Select a means to store this data apropriate for your backend environment.
In your server-side code, read the Origin request header and compare it to the list of allowed origins for the environment you are running in. If it matches one of them, add an Access-Control-Allow-Origin header with that value to the response.
For example, if you are using Node.js then:
Using .env.environmentName files is a common way to provide environment specific data.
The cors middleware will accept an array of allowed origins for the origin configuration option and will compare the Origin header to them and generate the right Access-Control-Allow-Origin header.

Related

How to fix blocked redirect due to CORS issues?

Here is my setup:
Running a local angular application on port 4200
Running an API using Deno on port 4300.
I have a use case where a client call at some api endpoint http://localhost:4300/foo, needs to redirect the user to another portion of the front end, say http://localhost:4200/bar#baz.
Currently this fails with the following error:
Access to XMLHttpRequest at 'http://localhost:4200/bar#baz' (redirected from 'http://localhost:4300/foo') from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
I have tried disabling/allowing cors on the API:
ctx.response.headers.set('Acces-Control-Allow-Origin','*');
ctx.response.headers.set('Acces-Control-Allow-Headers','*');
ctx.response.headers.set('Acces-Control-Allow-Methods','*');
ctx.response.headers.set('Access-Control-Allow-Credentials','true');
But this does not work.
Any ideas on how to fix this? Without setting up a proxy or installing a browser plugin.
Thanks!
See MDN:
The value "*" only counts as a special wildcard value for requests without credentials (requests without HTTP cookies or HTTP authentication information). In requests with credentials, it is treated as the literal header name "*" without special semantics. Note that the Authorization header can't be wildcarded and always needs to be listed explicitly.
You are making a request with credentials therefore you can't use * as a wildcard and have to be explicit about which headers you are using.

Setting and getting a cookie back from a javascript tag request

I have the following situation:
Javascript tag with src=domain1.com in another_domain.com page
Javascript tag returns a cookie header and script content from domain1.com server
Script content collects data and send it via request to domain1.com
I want to be able to set a cookie in the point 2 and recover it in the point 3. I've been able to set the cookie by returning a Set-Cookie header like this:
set-cookie: cookieName="cookieValue";Version=1;Domain=domain1.com;Path=/;SameSite=None;Max-Age=600;Secure
But I am not able to recover it in the request in the point 3, as the cookie is not sent with the request.
So, two questions at this point:
Do I need to manually send the cookie in the second request? When tested doing redirects, the cookie header is "autoattached" to the second request and I'm able to recover it, but this is not happening with the requests from the javascript tag.
I am only able to set a cookie in https (Secure cookie) and with SameSite=None from the script? When tried without Secure and SameSite=None or in an http environment, the cookie was not set and a cross-site error was thrown by the developer console.
Thanks for reading.
There are several things to consider here. First of all we have to note that we are facing a case of cross domain communications.
If you need to send in the step 3 the Cookie set by the server in the step 2, you have to explicitly configure it when making the request. In case you are using XMLHTTPRequest you have to set up withCredentials to true, here is the docs.
If you are using fetch take a look at Request credentials.
As it's a cross domain communication, make sure your CORS headers are properly configured. When the request credentials mode is "include" you will need to set the Access-Control-Allow-Origin header to something valid and not a wildcard "*". You will also need Access-Control-Allow-Credentials to true, check it here.
With this configuration, the cookie will be "autoattached" (as per your words) in the third step. You can't set a cookie via JS on a cross-domain setting for security reasons, see this response.

javascript: fetch blocked by CORS policy because of wildcard

I am trying to use the following api endpoint using fetch:
https://api.guerrillamail.com/ajax.php?f=check_email&ip=${ip}&agent=${agent}
(outdated documentation)
When I set credentials: 'include' I get the following error:
Access to fetch at 'https://api.guerrillamail.com/ajax.php?...' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
I have to set the flag in order to submit a cookie for authentication.
After googling this problem for 1++ hour, my understanding is the following:
CORS has to be server side allowed to be able to make "none simple" request to an other domain e.g. localhost => guerrillamail.com to prevent abuse, a variable Access-Control-Allow-Origin has to be set to the domains that should be allowed to send requests. A valid option is "*", which means that ALL origins are ok.
For some reason it is not ok though in combination with the credentials: 'include flag.
Do you have any ideas why this wouldnt be allowed?
Do you know what I have to do, in order to to do the request?
And is my understanding about this correct?
The documentation you're referencing no longer applies. In that old documentation, the API was made available over HTTP rather than HTTPS. CORS doesn't apply to HTTP and wouldn't have been a problem.
In the latest documention, that API is provided over HTTPS. To deal with the CORS requirement, they also removed the need for cookies, changing it to subscr_token and sid_token parameters sent as part of the request:
version 1.5, 30th May 2011
- Removed the requirement for cookies, added subscr_token and sid_token parameters

How do I permit cross-origin resource sharing selectively by authorization information?

Some users of my service wish to be able to access our REST API (which requires user credentials) via javascript in a browser. I will not allow this generally due to all of the vulnerabilities associated with violating the same origin policy. But if a specific user needs it and understands what is going on... I wish to add him to a "can make cross origin request" whitelist.
However, I cannot figure out how to selectively return a Access-Control-Allow-Origin header based on http authorization information.
If I do this in javascript:
$.ajax({'url':'url', 'beforeSend': function (xhr) { xhr.setRequestHeader("Authorization", "Basic " + 'base64encodedcreds' ) } })
The browser first sends an ORIGIN METHOD request without the Authorization header. Consequently, there is no way for me to know if I should include Access-Control-Allow-Origin in the response.
Is there some setting in the xmlhttprequest to get it to send an ORIGIN with the authorization? Or is there another way to selectively grant cross-origin access?
There's no way to bypass this behavior -- passing an authorization header is one of the bits of behavior that AAAO is trying to restrict. But you can sidestep it:
Create a separate endpoint URL for this user.
Have this endpoint always return an Access-Control-Allow-Origin that permits access. (Or whatever.)
Have this endpoint also always return 401 (not authorized) for any user other than the one you're trying to permit.
Based on duskwuff's answer that this was impossible I took this close route to not have to create new urls:
Always accept the options query with access-control-allow-origin
If a GET/POST comes in, check the options header. Check user credentials and 401 if user is not whitelisted.
(Very easy to pull off with django middleware)

Serving static files in connectjs with 'Access-Control-Allow-Origin' set to '*'

I'm using Connect.js to serve my static files in a Node.js application; however, I want to be able to make GET requests to those static files from multiple origins, so I'd like to be able to set 'Access-Control-Allow-Origin' : '*' in the response header for these static files.
My question is, how would I go about doing this with Connect? Here's my server so far:
var connect = require('connect');
var server = connect(
connect.static(__dirname + '/public')
);
server.listen(8080);
Access-Control-Allow-Origin only applies to ajax requests, generally speaking. When you're serving static files, you don't need to worry about that particular header. Anyone can request those files, regardless of origin, in the default configuration.
You run into issues when you serve a regular page, and then you want to request via javascript FROM that page. Then you need to set your Access-Control-Allow-Origin policy to allow ajax requests to other domains from that particular page.
Further, you most often run into this when attempting to access a web service. Its very common to use JSONP in those cases, instead of using that particular header. Especially not * since it introduces security risks. See http://www.ibm.com/developerworks/library/wa-aj-jsonp1/ and http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
MDN resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Josh

Categories

Resources