I'm trying to build my first API to be consumed by a mobile application built with Ionic.
Before starting I'm looking into the architecture and I can not understand exactly how to make secure my API routes.
Let's say I have an endpoint like http://myapi/v1/get-items and my application doesn't need an user to be authenticated to view those items in the mobile app.
How should I protect that route from external queries, using Postman for example?
I wish that route to be not accessible unless is not requested by the application.
Looking on Google I can find many solution using basic authentication but all of those require an user to log in... What if my app doesn't have users to log in?
I'm a bit confused but I think there is a solution and I don't know it yet...
I hope you can help me to understand it.
EDIT:
My Question is totally different from the following: How to implement a secure REST API with node.js
I'm looking for solution that DO NOT require a User Authentication.
If you don't want to use User Auth through something like Passport then you can institute a whitelist in your Node API instead. express-ipfilter is an express middleware module that allows you to filter requests based on the request IP.
Requiring a login would be the cleanest and safest way to make sure your api remains private. However, if you want to keep external users out of your services without requiring a login, you will need to "sign" your requests. By that I mean doing something like encrypting a current timestamp on the client using a key known to both the server and the client app, adding that encrypted string as a header, receiving that header in your server, decrypting it and checking that it's not too old of a timestamp before you return a response.
It's not really safe (if someone can see the code they can see the encryption key) but it's an obstacle and it down't require logging in. See this for an example on encryption/decryption
Related
I have a problem trying to figure it out for few days, still didn't get any rigid solution.
I have an angular app which will be publicly available so no login or credential is needed to open the website, and user can have an Id as query param. lets' say www.mysite.com/123
to retrieve data for 123, I have a backend, that needs authentication with clientId and clientSecret, to get access_token and then call the api with access_token to get information.
If I put clientId and clientSecret in the code a hacker can steal it and will be using it.
There were some suggestion to enable CORS on backend to make sure only requests from my site will be handled. which I already did, but with knowing the clientId and clientSecret even if CORS is enable a hacker can send requests from postaman by adding origin and referrer as header.
I tried Angular Universal for server side rendering hoping the api call will be run on serve side and will be hidden from user, but api call still happing in front end.
Really stuck in this problem any kind of help is appreciated.
Since the application is small and it's only hosting a web component developed by stencilJs, if other languages such as react or vue can support my scenario I can switch
You can go extensive ways of obfuscating statically inserted token in the frontend client build, yet it is still going to be there and the only thing it will add — extra steps for an attacker to reverse it, at least to my knowledge.
So to explore the solution to your problem, i guess you want to define it in the more narrow way, i.e what are you trying to protect:
resource requiring privilege (admin panel)
then your answer will be dynamic auth.
protect your api from external usage/ddos
CORS, ratelimiting, dynamic token issuing(take notice that strategy still will be available inside frontend client code)
also i think owasp guidelines will be a good read on the topic:
https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
I think i should clarify that in my opinion the solution that you are going to implement in the end in the case of the "protection of the api" is going to be building fences to jump over, rather than sealing api completely from the 3rd party usage.
How do I hide an API's secret access tokens in a production build of an app created with create-react-app?
I've visited this question but it does not have an acceptable answer to my question. I do not want to use process.env.REACT_APP_SECRET_VALUE in my app as this variable would be exposed in the client-side javascript.
Given that the production build of a create-react-app app is composed of static files only, the only solution I can think of involves only using APIs that use a combination of public client IDs and some form of backend client whitelisting, IP or otherwise.
Am I missing something here?
Like you already mentioned, you can request an api backend that only returns your secret if it's whitelisted IP.
But still can you be a litle more specific what are you trying to achieve, just guessing but maybe you need to look at direction of some authentication first so after that the user on the client side would be able to do something (see secret).
You're on the right track. If you're unwilling/unable to expose keys for services you're using, you may need to create an endpoint on a server somewhere that you call and have that endpoint proxy the relevant API request. Amazon's API gateway could probably handle this for you.
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html
I'm working with auth in Nextjs, I'm wondering what is the best strategy to handle authentication in NextJS ?
Here my services structure :
If I understand well I have to handle the server side rendering in NextJS, so I understand I have to put cookies from my external server to my NextJS client, then handle the server side rendering checkings. To do that I assume I have to create connection between the NextJS server and the other services. Before dive more deeper in the subject I would discuss with you about the possibilities available to me. It seems the NextJS auth is a subject in plain development.
Any hint would be great,
Thanks
I've recently added an example with cookie auth which explains what you are trying to do on the frontend.
For the backend, optimally you'll have your API in an external server, apart from the server you use for rendering your Next.js app. This API will handle the database and the token creation business. Then the basics of the authentication are like this:
The client POST a request with username and password to the server.
The server gets the request and generate a token based on the data received.
If everything went okay validating the data, the server responds with the token, e.g., { token: "secrettoken" }.
The client receives the token and saves it in a cookie. Optionally you redirect the user to the /dashboard or /profile if everything is okay.
The client, on restricted pages, will check if the cookie exists and optionally validate that against the server, you do this last part in getInitialProps. If the cookie validation fails you redirect the user away.
I've created a small library to abstract this logic.
So in the end, your Next.js app shouldn't know what's happening in the server, it only should receive the token, save it, validate it, and redirect the user if something is wrong.
How you want to handle the token creation, on the external server, is up to you.
Check out this thread. There are several examples of how to do Authentication with JWT, OAuth etc throughout the thread. You'll see that the examples are utilizing getInitialProps and there are several examples utilizing cookies throughout to extract the Authentication tokens.
You'll have to write a custom server.js file using express.js to serve the tokens through your route requests. I'm assuming by "external server" you mean some third party Authenticator using OAuth or OpenId protocols to retrieve tokens. If so, you're right to say that you'll need to request the tokens (or Authentication mechanism) from those external services and then decide how you're going to utilize them in your own client. You'll probably be using getInitialProps to do what you need to do with your Authentication tokens in the client once you are rendering to the browser.
More examples of Authentication here -- one for firebase and another for Apollo.
Just to add to the answers if you want to use Auth0 specifically. In the interview on http://www.fullstackradio.com/112 around the 1:06 min mark Guillermo Rauch mentioned that if he were to implement authentication all over again he would use Auth0, so I created a minimal repo using Auth0 and Nextjs with Serverless functions.
Like #jolvera suggested there is an API in an external server, apart from the server used for rendering the Next.js app. This API is located in ./auth/auth.js. It handles the token creation business, and could be extended to handle the database.
The HOC component in ./utils/withAuth.js calls the auth.js lambda for the user information, and is only able to retrieve it if the client side is authorized. Otherwise the user information is undefined. Additionally there is an event listener similar to the one in with-cookie-auth which syncs logouts across tabs.
Also one other note, don't get confused with the Nextjs example on Auth0's blog. That example is extending the Nextjs server, and isn't the solution you want if you are deploying Next to serverless. It doesn't have the separation of concerns with page routing and authentication.
I want to create an API at www.MyDomain.com that is accessible from public websites www.Customer1.com and www.Customer2.com. These public websites display each customers inventory and do not have any login features. They will use AJAX calls to read data from my API.
How can I secure the API so that it can be accessed via AJAX from different domains but no one can access the API to be able to scrape all of my customers data and all of their inventory?
I have tried thinking of different solutions on my own but they would all either require people to login to the public websites (which isn't an option) or it would require some secret "key" to be displayed publicly in the browser source code which could then be easily stolen.
Any ideas would be greatly appreciated.
Thanks!
P.S. Are their any obstacles that I am going to run into using Javascript & CORS that I need to look into now?
Anything that is accessible without authentication from a browser is by definition insecure, so you can't stop that. Your best bet is to have to have a relationship with the owner of customer1.com and customer2.com - the server apps for those two websites would make an HTTP call to you and authenticate with your service. Going this way also avoids the CORS issues you're talking about.
If you've already designed the client functionality, you can still probably do it without much change to the javascript - have it point to customer1.com for its AJAX call instead of your API, and customer1.com would accept this request and just act as a proxy to your API. Aside from the authentication, the rest of the request and response could just be pass-throughs to your API.
You can use Microsoft.AspNet.WebApi.Cors.
It's just need add ONE line at webapi config to use CORS in ASP.NET WEB API:
config.EnableCors("*","*","*");
View this for detail.
The simplest way to provide a minimum security here is to provide some kind of token system. Each app has its own token, or combination of tokens which it must pass to the server to be verified. How you generate this tokens is up to you and other than being linked to app's access, doesn't have to mean anything.
Provide a way for each API implementer to open an account with you. This way you will know who is accessing what and in some cases you can block/stop service.
For instance, a token can just be an MD5 hash:
7f138a09169b250e9dcb378140907378
In the database, this hash is linked to their account. On each request, they send this token with what they want. It is verified first to be valid, then the request is fore filled. If the token is invalid, then you can decide how to deal with it. Either don't return anything or return an "access denied" (or anything you want).
One thing to avoid is having a single token for everyone, though this can be a starting point. The reason for this is if some unauthorized app gets a hold of this token and exploits it, you have to change the token for everyone, not just the app that somehow leaked the token. You also can't control if someone has access to something or not.
Since you listed ASP.NET, I can also point you to WCF, which is fairly complex but has all the tools that you need to setup a comprehensive web service to service both you and your clients.
I hope this gives you a starting point!
EDIT:
There are security concerns here in the case that someone leaks their token key somehow. Make sure that you setup a way in which the app/your service do not expose the the token in anyway. Also have a flexible way of blocking a token, both by your clients in you, if it so happens that a token is exploited.
I'm working on a web app that is mostly static - just HTML/CSS/JS + assets. I'm using a Rack server (Thin, actually) to serve it.
While the app is mostly static, there are a couple of server-side needs that have cropped up along the way. Since the app needs to interact with those needs via JavaScript, I've added Sinatra to the stack to allow me to easily set up some routes to serve as a simple API.
One such API call is to send an email - the web app needs a way to send an email to users. I set up a route (/api/mail) that can be called with a POST that includes a JSON object, and Ruby will fire off an email (via SendGrid).
Here's my issue - by nature, these API calls are public. Most of the time, that is fine - but with the email API, I want to protect it so that nobody can just start sending malicious emails with a simple POST, posing as my app.
Problem is, I'm not quite sure how to authenticate this. The web app itself is the client, not the user, so a password or API key seems worthless, since anyone could just sniff out the POST header and grab the credentials that the app is posting to the API.
Is encrypting everything via SSL my only option, or am I missing some glaringly obvious solution?
At the end of the day, anything you do can easily be scraped. I would do some aggressive rate limiting by ip and session, don't think if anything else would be possible (or effective)