Securing a RESTful API - security

For my current side project, which is a modular web management system (which could contain modules for database management, cms, project management, resource management, time tracking, etc…), I want to expose the entire system as a RESTful API as I think that will make the system as more usable. The system itself is going to be coded in ASP.MET MVC3 however if I make all the data/actions available through a RESTful API, that should make the system very easy to use with PHP, Ruby, Python, etc… (they could even make there own interface to manage certain data if they wanted).
However, the one thing that seems hard to do easily (from the user's using the RESTful API point of view) with a RESTful API is security with ajax functionality. If I wanted something that was complex to setup and use, I would just create SOAP services but the whole drive for using a RESTful API is that it is very easy. The most common way of securing a RESTful API with with a key that is associated with a user. This works fine when all the calls are done on the server side however once you start doing ajax functionality, that changes. I would want the RESTful API to be able to be called directly from javascript however anyone who are firebug would easily be able to access the key the user is using allow that person access to the system. Is there a better way the secure a RESTful API where it does not make the user of the RESTful API do complex things just to set it up?

For one thing, you can't prevent the user of your API to not expose his key.
But, if you are writing a client for your API, I would suggest using your server side to do any requests to the API, while your HTML pages provide the data from the user. If you absolutely must use Javascript to make calls to the API and you still have a server side that populates the page in question, then you can obscure the actual key via a one-way digest algorithm in a timestamp-dependant way, while generating the page, and make it that your api checks that digest in a time-dependant way too.
Also, I'd suggest that you take a look into OAuth Nonces and timestamps a bit more deeply. Twitter and other API providers obviously have this problem too, so they must be doing something with the Nonce values.

It is possible to make some signature in request from javascript. But I'm hot sure, how 'RESTfull' urls would be with this extra info. And there you have the same problem: anyone who can see your making-signature-algorithm can make his own signature, witch you server will accept as well.

SSL stands for secure socket layer. It is crucial for security in REST API design. This will secure your API and make it less vulnerable to malicious attacks.
Other security measures you should take into consideration include: making the communication between server and client private and ensuring that anyone consuming the API doesn’t get more than what they request.
SSL certificates are not hard to load to a server and are available for free mostly during the first year. They are not expensive to buy in cases where they are not available for free.
The clear difference between the URL of a REST API that runs over SSL and the one which does not is the “s” in HTTP:
https :// mysite.com/posts runs on SSL.
http :// mysite.com/posts does not run on SSL.

Related

How do I properly setup and deploy a private API exclusively for my frontend?

I am currently working on a web application. The client is designed in Vue.js and the server application is made with node.js and express.
As of now I plan to deploy both the client-website and the node.js-app on the same server. Both will be adressed via two different, unique domains. The server will be set up manually with nginx.
The problem now is that this solution won't prevent a user from being able to send requests to the server outside the client that was made for it. Someone will be able to call the /register route (with postman, curl etc.) to create an account an 'unofficial' way. I think the only clean solution is that only my Vue.js-app would be able to perform such actions. However, since both the server and the client are two different environments/applications, some sort of cross-origin-request mechanism (cors for instance) must be set up.
So I'm wondering, is this bad by design or is it usual that way? If I wanted this not to be possible, should I see to that issue and try to make the express-API as private as possible? If so, what are usual best practices for development and deployment / things to consider? Should I change my plan and work on a complete different architecture for my expectations instead / How do 'bigger' sites manage to allow no requests outside the official, public developer API's?
I think the only clean solution is that only my Vue.js-app would be able to perform such actions.
An API that is usable from a browser-based application is just open to the world. You cannot prevent use from other places. That just how the WWW works. You can require that a user in your system is authenticated and that auth credential is provided with each request (such as an auth cookie) before the API will provide any data. But, even then, any hacker can sign up for your system, take the auth credential and use your API for their own uses. You cannot prevent that.
If I wanted this not to be possible, should I see to that issue and try to make the express-API as private as possible?
There is no such thing as a private API that is used from a browser-based application. Nothing that runs in a browser is private.
If you were thinking of using CORs protections to limit the use of your API, that only limits it from other browser-based applications as CORs protections are enforced inside the browser. Any outside script using your API is not subject to CORs at all.
How do 'bigger' sites manage to allow no requests outside the official, public developer API's?
Bigger sites (such as Google) have APIs that require some sort of developer credential and that credential comes with particular usage rules (max number of requests over some time period, max data used, storage limits, etc...). These sites implement code in their API servers to verify that only an authorized client (one with the proper developer credential) is using the API and that the usage stays within the bounds that are afforded that developer credential. If not, the API will return some sort of 4xx or 5xx error.
Someone will be able to call the /register route (with postman, curl etc.) to create an account an 'unofficial' way.
Yes, this will likely be possible. Many sites nowadays use something like a captcha to require human intervention before a request to create an account can succeed. This can be successful at preventing entirely automated creation of accounts. But, it still doesn't stop some developer from manually creating an account, then grabbing that accounts credentials and using them with your API.
When talking about web applications, the only truly private APIs are APIs that are entirely within your server (one part of your server calling something in another part of your server). These private APIs can even be http requests, but they must either not be accessible to the outside world or they must require credentials that are never available to the outside world. Since they are not available to the outside world, they cannot be used from within a browser application.
OK, that was a lot of things you cannot do, what CAN you do?
First and foremost, an application design that keeps private APIs internal to the server (not sent from the client) is best. So, if you want to implement a piece of functionality that needs to call several APIs you would like to be private, then don't implement that functionality on the client. Implement that functionality on the server. Have the client make one request and get some data or HTML back that it can then display. Keep as much of the internals of the implementation of that feature on the server.
Second, you can require auth credentials for a user in your system for all API usage. While this won't prevent rouge usage, it will give you a bit more control because you can track usage, suspend user accounts when you find abuse, etc...
Third, you can implement usage rules for your public-facing APIs such as requests per minute, amount of data, etc... that your actual web application would never exceed so if they are exceeded, then it must be some unintended usage of the API. And, you could go further than that and detect usage patterns that do not happen in your client. For example, if you see an API user cycling through dozens of users, requesting all their profiles and you know that is something your regular client never does, you could detect that type of usage and block it.

How to verify the requester of a Node API

I have a Cloudflare Worker that presents a registration form, accepts input from the user that is posted back to the Worker which then sends that on to an Node HTTP API elsewhere (DigitalOcean if that matters) that inserts the data into a MongoDB (though it could be any database). I control the code in both the CF-Worker and the API.
I am looking for the best way to secure this. I am currently figuring to include a pre-shared secret key in the API call request headers and I have locked down what this particular API can do with database access control. Is there an additional way for me to confirm that only the CF Webworker can call the API?
If this is obvious to some I apologize. I have always been of the mind that unless you are REALY good at security it is best to consult those who are.
You can research OAuth2.0 standard. That is authorization standard for third party clients. Here is link: https://oauth.net/2/
This solution is the most professional.There are other less secure ways to do it, but easier to implement. Password and username, x-api-key, etc..
It sounds to me that you can also block all IPs and allow only requests from that specific domain name (CF Worker)

How to make Node API only accessible by web app?

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.

How to secure server API in order to reject fake-client calls?

I'm developing both server and client side of a web application and it is almost finish. Now, it is time to secure it.
I read lots of articles and Q-A sites to understand the principles of the concept. But there are still question marks on my mind.
There is a similar question here:
How do I secure REST API calls?
They suggested to use token-based security system, which is very common and practical way. Also services like Firebase, Auth0 are providing this security system.
And this is about "how and where to store token": https://auth0.com/docs/security/store-tokens
If so, how can token protect server from fake-calls while we are storing it in the browsers local storage?
Explaining it with an example in order to be clear:
My client-side code has a form with options. One of the option can be selected via drop down option and there are only "1,2,3,4" in those options. So that, client can never send a form with "5" value to the server. But what if someone use a API tool (for example postman) to send a form with a value of 5? Attacker still can add a token to that request. First login to system as normal user. Than open the developer console of the browser, copy your token and paste to the header of your fake-request.
Not allowing the cross origin calls may solve the problem. But I am not sure if this means server and client should run on the same domain (or host)?
Bonus from stackoverflow: Stackoverflow's use of localstorage for Authorization seems unsafe. Is this correct else how do we strengthen it?
They are also discussing the similar question from another aspect. (Not for the server security but for the user's security.)
Not related but in case of need: front-end is developed with Angular 5, server is developed with Java and Spring Framework.

Securely decouple backend and frontend (node.js server)

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.

Resources