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.
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.
In node, if I use a library like axios and a simple async script, I can send unlimited post requests to any web server. If I know all parameters, headers and cookies needed for that url, I'll get a success response.
Also, anyone can easily make those requests using Postman.
I already use CORS in my node servers to block requests coming from different origins, but that works only for other websites triggering requests in browsers.
I'd like to know if it's possible to completely block requests from external sources (manually created scripts, postman, softwares like LOIC, etc...) in a node server using express.
thanks!
I'd like to know if it's possible to completely block requests from external sources (manually created scripts, postman, softwares like LOIC, etc...) in a node server using express.
No, it is not possible. A well formed request from postman or coded with axios in node.js can be made to look exactly like a request coming from a browser. Your server would not know the difference.
The usual scheme for an API is that you require some sort of developer credential in order to use your API. You apply terms of service to that credential that describe what developers are allowed or are not allowed to do with your API.
Then, you monitor usage programmatically and you slow down or ban any credentials that are misusing the APIs according to your terms (this is how Google does things with its APIs). You may also implement rate limiting and other server protections so that a run-away developer account can't harm your service. You may even black list IP addresses that repeatedly abuse your service.
For APIs that you wish for your own web pages to use (to make Ajax calls to), there is no real way to keep others from using those same APIs programmatically. You can monitor their usage and attempt to detect usage that is out-of-line of what your own web pages would do. There are also some schemes where you place a unique, short-use token in your web page and require your web pages to include the token with each request of the API. With some effort, that can be worked around by smart developers by regularly scraping the token out of your web page and then using it programmatically until it expires. But, it is an extra obstacle for the API thief to get around.
Once you have identified an abuser, you can block their IP address. If they happen to be on a larger network (like say a university), their public IP address may be shared by many via NAT and you may end up blocking many more users than you want to - that's just a consequence of blocking an IP address that might be shared by many users.
I'm developing a web app with React and an GraphQL API with Node.js / Express. I would like to make the API more secure so that its harder for API requests that don't come from the web app on the browser to get data. I know how to do it with registered users. But how to make the non-registered user still be able to access some basic data needed for the app?
Is it possible to put some kind of key in the web app - so the API call can't be replicated for others through sniffing the network dev tool in browser and replicating in Postman? Does SSL/TLS also secure requests in that browser tool? Or use like a "standard" user for non-registered visitors?
Its a serverside web app with next.js
I know theres no 100% secure api but maybe its possible to make it harder for unauthorized access.
Edit:
I'm not sure if this is a problem about CSRF because Its not about accessing user data or changing data through malicious websites etc. But its about other people trying to use the website data (all GET requests to API) and can easily build there own web app on top of my api. So no one can easily query my api through simple Postman requests.
The quick answer is no you can't.
If you trying to prevent what can be describe as legit users form accessing your api you can't really do it. they can always fake the same logic and hit your webpage first before abusing the api. if this is what your trying to prevent your best bet is to add rate limiting to the api to prevent a single user from making too many request to your api (I'm the author of ralphi and
express-rate-limit is very popular).
But if you are actually trying to prevent another site form leaching of you and serving content to their users it is actually easier to solve.
Most browsers send Referrer header with the request you can check this header and see that requests are actually coming from users on your own site (this technique is called Leech Protection).
Leaching site can try and proxy request to your api but since they all going to come from the same IP they will hit your rate limiting and he can only serve a few users before being blocked.
One thing the Leecher site can do is try to cache your api so he wont have to make so many requests. if this is a possible case you are back to square one and you might need to manually block his IP once you notice such abuse. I would also check if it's legal cause he might be breaking the law.
Another option similar to Referrer is to use samesite cookies. they will only sent if the request is coming directly from your site. they are probably more reliable than the Referrer but not all browsers actually respect them.
I've been looking at node.js, REST APIs and WebSockets lately to further my knowledge about backend and frontend web development. Trying to go with best practices I see REST API comes up all the time. Now my problem which I don't seem to understand how to properly solve.
Say for example I'd like to have client / server decoupled and for this I implement a REST API in the backend so that my frontend will access and get data to render. Specific (imaginary) example: lets say I want to build a rental service website. Now I would like to have an endpoint for my frontend to access information about certain products, let's say the number of bikes that have been rented so far. I'd like to be able to show this on my frontend (through the help of the REST API) but I wouldn't like for other people who call this REST API to be able to get the data (because espionage is a serious business and I'd like to keep the evil ones away, yes they can webcrawl but bla bla). So in essence I'd like for the localhost machine to be able to access (part of) the REST API but not anyone else. Things get complicated because I'd also like people to be able to create a user on my website so then I'd like to have other endpoints which can then be accessed without restriction because I'm thinking, what if at some point I'd like to have a mobile app that is integrated with the service. Then it will be unfeasible to restrict all requests to localhost.
How would you architect a secure server / client as this one? Or in your opinion is it not that big of a deal to have the REST API exposed to others (the evil ones)?
The above goes for WebSockets as well. I know REST APIs are all nice and neat but I think the future lies in near-realtime connections and so I'm likewise as interested in WebSockets (through higher level modules of course, Socket.io, SockJS etc.).
There are many solutions to secure your API out there and many of them are opensource. Which one you'll use really depends your detailed needs.
But to get you started I will mention a solution that is very accepted and supported by a large community:
Have a look at JSON Web Token, which are for example explained in this Article.
Basically your client requests an authentication token from the server and then stores it locally to reuse it for every request to your API.
The Server on the other hand may protect your API as needed. That means you may also have a public API that does not expect a token in the HTTP Header.
Tokens may also expire. That is handy if you, for example, will allow a new user for registering on your site for a limited time.
Here is another article that explains things.
Now on to the websocket part of your question. YES, you definetly want to protect your server side sockets as well. So look out for a library that supports authentication. Again, I think there are a number of opensource libraries out there.
To mention one: Primus.
Primus is an abstraction layer for many socket libraries underneath and lets you quickly change the socket provider. But it also has an authentication hook that you can implement.
And guess what.. you can use it to check for a JSON Web Token!
Hope this gets you started.
I'm developing a web application using Java EE and some open source components (Spring, Struts 2, jQuery, and so on). Some of my web pages require authentication (Spring Security) and other not. I write some REST APIs (Restlet) and I use them from my pages by AJAX calls (jQuery). I know that other web sites can not use my REST APIs unless I enable CORS and this is what I want.
However any non-browser client (curl, Java applications, and so on) can call my REST APIs: how can I forbid this? I can not use authentication for all REST APIs because I use some of them in web pages that should not require authentication. I know that some APIs (like Facebook SDK) require an application-id in order to enable calls, but anyone can steal the key from the Javascript code included in my web pages.
I would like to recognize from the server side if an HTTP request has been sent from a browser or other client applications in order to apply some kind of authentication only in the second case. As I concern, any client application can set any HTTP header, so I can not HTTP headers, can I? I think that my problem should be a common problem, so maybe I miss something.
There's nothing you can do.
Most folks are worried about unauthorized users using their applications. You're worried about unauthorized programs.
Yet everything that a program needs to communicate with your server, it will be told (by the server as in a token, or by the user as in a credential).
Why are you afraid of "non-browser" clients? Why do you care what client they use? How is a non-browser client different than a normal browser for your use cases?
Answer that question, and you'll find better answers.
Are you afraid they'll "screen scrape" your site, quickly download it with something like wget? Then you can put in some server side rule gating their access (if IP x.y.z.w makes more than Q requests per BLEEM of time, then discard request/sleep 10s/send content REALLY slowly).
Those kinds of measures are what you have to do. You can't "secure" the client, it's not your client to secure. You have to secure your server, and address the concerns head on.
Remember rule #1 of client/server design: "Never trust the client". On the internet, no one knows you're a bot.