I thought about a couple ways but none of them would work:
- Encrypt the API Token with a strong algorithm.
- Authenticate for every API request:
- Make the API Token is “expirable”.
- Check the IP address of the request, which you could blacklist or whitelist it.
- Detect suspicious API requests, such as X no of requests within N interval, which you may disable or return different response, which you could define the rules here.
You cannot protect a security token that is going to be used from the web browser. This is why API’s that have sensitive security tokens do not allow browser access by blocking CORS.
In these cases, people using the API have to proxy the call to the API by calling a server script (that they control), the server script then queries the API with the secure token and returns the results to the web browser.
In this way the secure token is never visible to the browser.
On the server side you can control access to your script with a session (cookie / JWT etc). That way nobody can call your script directly and in so doing you protect the request to the API that requires a token.
IP checking only works in server-to-server requests. If you have a page that is going to be accessed on the web by people who will have a range of potentially changing IP’s:
- It is impractical to ask everyone who you want to give access to your API to give their IP
- IP’s change all the time – so you will have to keep doing it
What you can do for your API is protect it further by putting in code that says only the server that runs your proxy script can call the API. This would be a good idea and common practice but not from the web browser perspective.
You can’t stop the interception if the “man-in-the-Browser” when it is in effect. It is the same that token is stored locally on the user device which may well not be secured and infested with malware.
Rather, I will consider assume breach scenario and be prepared:
- Revoke compromised tokens immediately. If you’re using a revocation list on your server to invalidate tokens, revoking a token can instantly boot the attacker out of your system until they get hold of a new token. While it is a temporary solution, it will make the attacker’s life slightly more difficult.
- Force your client to change their password immediately. In the context of a web or mobile app, force your user to reset their password immediately, preferably through some sort of multi-factor authentication flow like the ones Okta provides. By requiring multi-factor authentication, you can have more confidence that the user resetting their credentials is who they say they are and not an attacker.
Tools to check for JWT implementing best practice:
Use HTTPS. If you use single use tokens or token/session (the common pattern), this will suffice.
Step 1: Create a session.
Step 2: Session gets a unique identifier – token, session id, whatever.
Step 3: Where the session expires after some amount of disuse, say 15 minutes or 30 minutes, or whatever you like, at which point token is destroyed, which logs out or breaks the session to the user.
Tip: Study how WordPress handles this + use some similar process.