Each Answer to this Q is separated by one/two green lines.
I’m setting up a webapp with a frontend and a backend that communicates with the frontend soley through RESTful methods. How do I make sure that the backend endpoints are only accessed by my own frontend, and not anyone else? I cannot find much information on this.
How do I make sure that the backend endpoints are only accessed by my own frontend, and not anyone else?
Let me tell you here a cruel truth… is not possible for a web app, due to the
nature how the web was designed to work.
Let’s try to understand the problem a little more in depth by understanding the
difference between WHO and WHAT is accessing your API server, and why private
API’s don’t exist.
WHO AND WHAT IS ACCESSING THE API SERVER
The WHO is the user of the web app that you can authenticate,authorize and identify in several ways, like using OAUTH flows and/or OpenID.
Generally, OAuth provides to clients a “secure delegated access” to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
Now you need a way to identify WHAT is calling your API server and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server, is it really your genuine web app or is a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
No matter if an API doesn’t have public accessible documentation or if is is protected by any kind of secret or authentication mechanisms, once is accessible
from the internet is not private any-more, thus can be accessed by anyone who
knows where it lives and enumerating each endpoint is easy as using the network
tab in the the dev tools.
Anything that runs on the client side and needs some secret to access an API
can be abused in different ways and you can learn more on
this series of
articles about Mobile API Security Techniques. While this articles where done in
the context of a mobile app, they still share common techniques with web apps.
They will teach you how API Keys, User Access Tokens, HMAC and TLS Pinning can be
used to protect the API and how they can be bypassed.
You may also want to take a look into the reCaptcha V3 from Google that will allow to distinguish real users
from automated scripts without requiring user interaction. You will need to add it to every page in your web app.
reCAPTCHA is a free service that protects your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive challenges to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.
Another more sophisticated way is to use User Behaviour Anlytics(UBA) tools that employ machine learning and artificial intelligence in the backend to prevent API abuse, but they are not able to block it at 100%.
To solve the problem of WHAT is accessing your API server you need to use one or all the solutions mentioned in the series of articles about Mobile API Security Techniques, reCaptcha V3 and a UBA solution and accepted that they can only make unauthorized access to your API server harder to bypass but not impossible.
So you can make it hard to find and access your API, but to truly lock it to your web app you can’t.
Look into CORS. And make sure your server only allows access to specific origins.
On the backend – check if the
X-Requested-Withheader is present in the request and set to
XMLHttpRequest. Without a proper CORS handshake this header will be absent.
That being said, this will only protect your API from being used by other front-end apps or from being accessed directly from a browser address bar – because browsers respect CORS. People can still forge requests programmatically/CLI and set headers to whatever they want.
So this is not actually “securing” just a way to prevent abuse & hotlinking