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();
})
Related
I have setup and application which uses a React front-end and Expres/NodeJS back-end. There is an ALB in the mix as well.
So, here is how the flow goes:
The ALB listens on port 443 and there is an Authentication action attached to the listener. This action uses and Amazon Cognito user pool, scope is openid. Once the authentication is successful the ALB redirects the request to the React app which in it's turn sends http requests back to the ALB which redirects them to the Express app on the server-side. I have setup the communication between FE and BE like this because we use Amazon ECS and I don't have a static DNS or IP except for the ALB.
I am unable to get the x-amzn-oidc-data header when console logging the req.headers. This header is important to me because I'd like to verify and work with the JWT that it contains.
I have read most of the docs on the Internet and they say that the ALB automatically sends this header (and couple of others) to the back-end. However, I only see one x-amzn-trace-id which has nothing to do with the JWT issued by Cognito.
Where do you think is my error? My setup seems pretty standard to me - how could I get that header?
Thanks in advance!
I have currently configured express-gateway to communicate with a service on my backend exposed on a unique port on my machine and it's working fine. The gateway serves as a proxy to the services and currently does some security checks and jwt authentication. Then, only authorized request (through jwt validation) gets sent to services as configured. However, I'm concerned that if I don't put some sort of authentication on my service, then anyone who knows the port (or URL) my service runs on can directly access it and bypass the gateway directly. I'm looking for a way I can set up a sort of auth between the gateway and the service (maybe through keys) so that only the gateway can communicate with the services and not any other client. I currently can't find anything in the docs specifically for that. Also, if there's something wrong with my architecture, I'd appreciate it if you could point it out. Thank you.
The path between Express Gateway and your back end should be on a private, encrypted network so there is no way for anyone to bypass the gateway.
With this architecture, you don’t need to authenticate on the server side, and if you use Express Gateway scopes, you don’t even need to check whether the user is authorized to perform the requested action.
I have a webservice working on a domain say www.abc.com . I want to configure my server so that none of the request coming from another domain (except from www.abc.com) will be accepted. I should not use user authentication or anything related to token based authentication. So, the only option i can think is CORS but i do not exactly know how to use it. Any help would be great.
I am using nodejs and express
Don't set a CORS header. Done.
To address your comment: Postman doesn't make Ajax requests, it makes requests. If you don't indicate in Postman that it's an Ajax request, it's just a standard client request.
See also how Postman send requests? ajax, same origin policy for some more details.
We are currently working on a nodejs application which hosts API's (includes both get and post HTTP methods). These server API's in nodejs server are individually accessible or allowed to be called. Like /api/login (login api) is allowed to be called directly from clients.
Next, I want to introduce a service broker API which should be entry point to all API calls from client side. So, any client calling a specific API such as /api/login should go through service broker and then service broker should re-direct to requested API based on the specific service details as sent by clients.
Thereby, all clients should only be able to call only one API (i.e. broker service API - /broker/service). So, all requests from clients should first hit service broker API and then service broker should redirect to appropriate API's based on the input parameters passed to service broker from clients. Input parameters could contain the API URL and input data.
Currently, I'm able to connect directly to individual API's from clients. But, now I would like to introduce a new layer namely service broker and that broker service should decide which API the request should be redirected along with input data (sent from clients).
Note: Both broker service API and other functionality specific API's are hosted under same domain. So, there will not be any CORS issue. We are using "express" node module for handling HTTP API requests.
My initial question is whether this requirement can be achieved?
If yes, then can we perform internal redirection of API's in node server?
Can this be achieved with express node module?
Please help me in this regard.
If you really wanted to go this route, you could do something like this:
app.get('*', function(req, res){
the_route_passed = req.originalUrl;
//handle all of the routes here in your api function call.
});
What this will do is for every single route passed from the front-end will go through your function, and then you can grab the route that was passed req.originalUrl will be like /api/users/230 for user 230. Then you'll need to parse the route or however you want to do it and pass it through to your service broker.
This would be the best way to deal with not having to change anything on the front-end if you are already using Routing. The other way which might be better in the long run:
Send JSON on each request and configure it however you want, and then when you receive it you can figure out all the routing from the JSON request on each go. You'd have to rewrite all routes on the front-end to do this though which might be too much work.
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.