I have an electron app set through the React CLI. It seems to work fine but when I try and do an external HTTP request though:
https.get('https://blockchain.info/q/24hrprice', (result) => {
console.log('RATE: ', result);
});
I get:
Fetch API cannot load https://blockchain.info/q/24hrprice.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
If an opaque response serves your needs,
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
You're making a cross-origin request (your requesting domain is different than the API's domain) and browsers have special rules around that. In a Node context (i.e. via node's http/https modules), you don't have to worry about CORS and can in general do lower level work on network requests. Browsers, on the other hand, have a lot of security around CORS. When you use fetch your network request is going through Chromium's networking layer and so it's subject to those restrictions. When you use node's http/https, you're using node's. It's sort of a confusing point about Electron--a renderer process seems like a normal web context but you actually have access to all of node.js' APIs too, allowing you to things you can't do in a plain browser.
I would check and see if including an API key in that request changes the response of the API (maybe that triggers their API adding the appropriate CORS headers like Access-Control-Allow-Origin). Maybe the API wasn't meant to be called within a browser context and so a more node.js oriented approach is the way to go.
This is a great article on CORS and the ways to deal with it: https://medium.com/#baphemot/understanding-cors-18ad6b478e2b
Related
I am building a Next.js application in which I want to restrict access to my APIs. I only want my application to make those requests.
I once built an app with MERN stack, and I remember I used cors to only allow my domain to make requests to my APIs. But apparantly cors does not work with nextJS, and I tried many npm modules such as nextjs-cors but they didn't work.
I am thinking about using firebase App Check in order to check if this is my app that is making the requests, but I am still hesitant.
What do you think is the optimal and professional solution for this?
P.S.: Is there a similar behavior to cors in but in NextJS because I also remember cors did not allow postman to make requests as well to my APIs.
That is what API keys are for. Since you have control over both client and server, in client requests you can add a random key to headers when you make request. Then on the server, you can extract the headers console.log(req.headers), if the headers include the specific key and matching value, you process the request if not you reject the request.
I've read an article which used Cors-Anywhere to make an example url request, and it made me think about how easily the Same Origin Policy can be bypassed.
While the browser prevents you from accessing the error directly, and cancels the request altogether when it doesn't pass a preflight request, a simple node server does not need to abide to such rules, and can be used as a proxy.
All there needs to be done is to append 'https://cors-anywhere.herokuapp.com/' to the start of the requested url in the malicious script and Voila, you don't need to pass CORS.
And as sideshowbarker pointed out, it takes a couple of minutes to deploy your own Cors-Anywhere server.
Doesn't it make SOP as a security measure pretty much pointless?
The purpose of the SOP is to segregate data stored in browsers by their origin. If you got a cookie from domain1.tld (or it stored data for you in a browser store), Javascript on domain2.tld will not be able to gain access. This cannot be circumvented by any server-side component, because that component will still not have access in any way. If there was no SOP, a malicious site could just read any data stored by other websites in your browsers.
Now this is also related to CORS, as you somewhat correctly pointed out. Normally, your browser will not receive the response from a javascript request made to a different origin than the page origin it's running on. The purpose of this is that if it worked, you could gain information from sites where the user is logged in. If you send it through Cors-Anywhere though, you will not be able to send the user's session cookie for the other site, because you still don't have access, the request goes to your own server as the proxy.
Where Cors-Anywhere matters is unauthenticated APIs. Some APIs might check the origin header and only respond to their own client domain. In that case, sure, Cors-Anywhere can add or change CORS headers so that you can query it from your own hosted client. But the purpose of SOP is not to prevent this, and even in this case, it would be a lot easier for the API owner to blacklist or throttle your requests, because they are all proxied by your server.
So in short, SOP and CORS are not access control mechanisms in the sense I think you meant. Their purpose is to prevent and/or securely allow cross-origin requests to certain resources, but they are not meant to for example prevent server-side components from making any request, or for example to try and authenticate your client javascript itself (which is not technically possible).
How can I make Varnish work like a switch?
I need to consult an authentication service with a request of the original client request. That authentication service checks upon original request if access is permitted and replies simply with a status code and probably some more information in the header. Upon that status code and header information from that auth service, I would like varnish to serve content from different backends. Depending on the status code the backend can vary and I would like to add some additional header before Varnish fetches the content.
Finally varnish should cache and reply to client.
Yes, that's doable using some VCL and VMODs. For example, you could use the cURL VMOD during vcl_recv in order to trigger the HTTP request against the authentication service, check response, and then use that info for backend selection and other caching decisions (that would be just simple VCL). A much better alternative would be the http VMOD, but that one is only available in Varnish Enterprise. In fact, a similar example to what you want to achieve is available in the linked documentation; see 'HTTP Request' section.
In any case, it would be a good idea to minimise interactions with the authentication service using some high performance caching mechanism. For example, you could use the redis VMOD for that (or even Varnish itself!).
as far as i know 'Access-Control-Allow-Origin' is used as part of CORS to limit which all hosts can request data from a given api server. This flag/variable value is set by the server as part of a response.
I did happen to stumble upon this chrome extension which says:
Allow to you request any site with ajax from any source. Add to
response - 'Access-Control-Allow-Origin: *' header
Developer tool.
Summary Add to response header rule - 'Allow-Control-Allow-Origin: *'
Hint Same behavior you can get just using chrome flags [http://www.chromium.org/developers/how-tos/run-chromium-with-flags]
chrome --disable-web-security
or
--allow-file-access-from-files --allow-file-access --allow-cross-origin-auth-prompt
so that means from the client side I can change the response header. So it means that if i set on server : 'Access-Control-Allow-Origin : http://api.example.com' this setting can be overwritten by client 'Access-Control-Allow-Origin : *'. or may be I do not want to support cors - so i dont set it, but this will still show as if I do support CORS.
If that is the case, what is the point in having my server side setting?? isn't that left redundant??
May be I am being too naive here, and not getting the basics of it.
CORS is a security feature to protect clients from CORF, or Cross Origin Request Forgery. It is not intended to secure servers, as a client can simply choose to ignore them.
An example of CORF would be visiting a website, and client-side code on that website interacts with another website on your behalf, do things like submitting data to a website, or reading data that requires authentication as you, all with your active authentication sessions.
Theoretically, without CORS, it would be possible to create a website that will fetch your email from a webmail provider (provided you are logged in at the time), and post it back to a server for malicious individuals to read.
To avoid this, you shouldn't browse the web with such security features disabled. It's available to ease development, not for general browsing.
Looking through the Firebase FAQ I can't see how cross domain issues are handled. Obviously, we don't want to serve on the Firebase domain, is it CORS, hidden iFrame, other? Would we need to create a sub-domain that points at the IP of the sharing server?
Let me answer this question in two parts, as there are multiple ways to communicate with the Firebase Servers.
Firebase JavaScript Client - The Firebase Javascript Client maintains a real-time bidirectional connection to the server. Under the covers, this uses WebSockets whenever possible (which have no limitations with regard to cross-origin connections) and falls back to hidden-iframe-based jsonp long-polling on older browsers (which sidesteps cross-origin issues by only doing requests).
Firebase REST API - You can also get / set data from Firebase using the REST API, which uses CORS to allow cross-origin requests.
So in summary, it should "just work" and you don't need to do anything special.