I am building a REST API with sails js and I want to allow only a specific white list of hosts to request it. I know that this can be configured in CORS config file for Browser to Server requests. But in my case, I need it for Server to Server requests. Thanks
CORS of course can't restrict server-server request because it's applied to browser. You must specify it in controller, maybe some kind like using special key request or any kind of authentication that only some requester with some secret key are allowed to access.
Related
I've developed simple REST API using a expressJs. I'm using React as my client side application. So the problem is anyone can see my API endpoints because of react app is in client side. So they will also able to make request and fetch data from my REST API. (May be they will build their own client side apps using my API.) I've seen some question about this and couldn't find any comprehensive answer. How these kind of a security problem should be handled? Is it possible to give the access for API to only my client app? If not how huge brands that using REST API prevent that? (Also I don't have a user authenticating scenario in my product as well. People can just visit and use the website. They don't need to register).
Authentication can be a way but it can be bypassed. Another way is you can create a proxy server which strictly blocks cross origin requests, hence it blocks requests from other domains to make request to your API, and you can make your API call from that proxy server. In this way your API server endpoint will also be not compromised.
If, as you state in your comment, this is about users on your own website being allowed to use your site's API, while disallowing off-site use (e.g. other websites, wget/curl, etc) then you need to make sure to set up proper CORS rules (to disallowed cross-origin use of your API) as well as CSP rules (to prevent user-injected scripts from proxying your API), and you also make sure to only allow API calls from connections that have an active session (so even if you don't want user authentication: use a session managemer so you can tell if someone landed on your site and got a session cookie set before they started calling API endpoints).
Session management and CORS come with express itself (see https://expressjs.com/en/resources/middleware/session.html and https://expressjs.com/en/resources/middleware/cors.html), for CSP, and lots of other security layers like HSTS, XSS filtering, etc, you typically use helmet.
I was wondering if it is possible to secure an expressjs RESTful API that only a react native app and react website could access.
For exemple my server is running on port 8000, my react native app is on port 3000 and my website on port 5000. I want the server to listen only to requests coming from these ports.
Let's say I have a POST route to mydomain.com/signup I don't want users to make that post request using external websites or tools like Postman.
What would be the best way to ensure my mobile app and Web site are the only ones allowed to access my RESTful routes.
First off, you are a bit mistaken about how a request to your API works. When your react app on port 3000 makes a request to your server on port 8000, it's just a random incoming request. It doesn't "come" from port 3000. In fact, the incoming port number with be some randomly generated port with 5 or 6 digits. Outbound ports are dynamically generated by the TCP system and you can't tell what "app" it came from.
Second off, your RESTful API server is just a server on the internet. Anyone can make a request to it. Using cross origin protections, you can provide some limits about what can be done from browser Javascript (only allowing requests from your particular domain's web pages), but other requests (not from a browser) cannot be blocked this way.
So, any code jockey using any tool other than a browser can write code to your API. What someone like Google does is they require you to either have an APIKey that they issued to you or they require some login credentials (often a cookie from a previous end-user login) that identifies the user making the request as a permitted user using their system. Even with these tools, this just means that a permitted user is accessing the API, it does not mean that only your app is accessing the API. And, in fact, you can't really prevent that.
So, what most people do is they require a login or APIKey credential and they track the type of use of the API. If the use of the API seems appropriate (particularly the types and frequency of requests), then that use is permitted. If the use of the API does not seem appropriate (often too many requests over some period of time), then that particular credential or user may be blocked from accessing the service either temporarily or permanently.
Let's say I have a POST route to mydomain.com/signup I don't want users to make that post request using external websites or tools like Postman.
You cannot effectively do this. There are obstacles you can erect to make it more difficult like putting an expiring token in your web page and having your own use of the API include the token and then detecting if its a valid token, but a determined hacker will just scrape the token from the web page and still access your API using it from whatever programming tool they want.
What would be the best way to ensure my mobile app and Web site are the only ones allowed to access my RESTful routes.
You can't. Your API is on the web. Anyone with whatever credentials you require can access it.
I have a public React JS website which makes a request to my Node server using CORS (Only allowing the domain of my website). My website just fetches GraphQL queries from the frontend. But my Node server code do have GraphQL mutations like adding or deleting content. So, does this make my database insecure even though the CORS allows only my website which has no mutations?
The same-origin policy and CORS are only enforced by web browsers, and even then they can be disabled by individual users. You need to implement proper authentication and authorization for your server application in order to prevent unauthorized access to restricted fields like those on your Mutation type or other fields that may contain private or sensitive data that should not be exposed to all users.
I have a Node.js express server deployed to AWS EBS, the client side, written in React is deployed to S3 bucket as a static web page.
I'm working on some sort of sign up system to a specific service, and I don't want to request credentials from the user, so I guess csrf \ jwt is not going to work.
Is there anyway to block all http requests from origins other than the client? right now, there is a chance someone will just use Postman and make requests to my server, for example creating user with just an email.
I tried using private API Gateway, but I couldn't find a way to let the client make requests successfully.
I thought about encrypting the http requests payload, but I didn't find anyway to store a private key where it is not visible for anyone through the browser...
The origin is just an HTTP header that someone could set, i.e. "spoof", in their Postman requests. You can check the origin to block random scanner bots, but it isn't going to block anyone that is determined. So please don't confuse this as actual security. You could do this with AWS Web Application Firewall attached to your EB load balancer, or just adding a check in your express middleware as in the other answer.
Regarding private API Gateway, that would never work in this scenario, that is only for resources inside a VPC network, and your React app is running in people's web browsers on the public Internet.
Regarding someone creating a user account "with just an email" that is on you to handle, you should be completely validating the request on the server side, with the knowledge that the request may have come from someone using a tool like Postman since there is no way to totally prevent that in your scenario.
If you want to use API Gateway for this you could try implementing request validation there. You could also attach a Web Application Firewall to the API Gateway. I believe you could also do the origin header check as part of an API Gateway request validator.
You cannot block all the HTTP requests but surely can reject by adding a middleware
app.use((req, res, next) => {
if(req.protocol === 'http' && req.hostname!== <client domain>){
return res.sendStatus(403);
} next();
})
By using Node and Express, can I allow only HTTP REST calling from a specific mobile app?
For security reason, I want to achieve these:
1. Allow only specific IP range. Since both of the app is hosted using Azure website.
2. Allow only connection from specific mobile app.
Use CORS or JSONP
In CORS
For example, to allow http://mozilla.com to access the resource, you can specify:
Access-Control-Allow-Origin: http://mozilla.com
You can check HTTP Headers to get the client ips, see here
Check the ip with your IP list and only return if it is success.