API Security : Randomly Generated Secret
So one of the ideas I have been playing with for awhile was the idea of randomly generating your ‘secret’ used for token generation and other hashes.
I was hesitant at first because it could cause issues with the architectural call flow for the client response but it doesn’t and I wanted to explain why and why this is a good procedure.
Load Balancers Maintain Session
First doing something like this could backfire horribly if you had a user come in with a hash/token assigned to one server by your load balancer and then it send it to another upon an API request.
This doesn’t happen though. Load balancers/proxies/gateways all maintain session unless you configure them NOT TO.
Multiple Apps per Application/Web server
The other issue would be that you have multiple apps per server.
If you implement any kind of SSO across apps and want to access another app with the same token, the load balancer may send you to another server (not the same one issueing/handling tokens).
First, if you are not doing ‘web hosting’ (very 90's), this is not a problem because you will only do ONE APPLICATION per SERVER.
How Is It Done?
Allow me to explain in Java / Springboot…
First I create an object for generating and storing the secret in the app:
public class SecretGenerator {
private String secret;
public SecretGenerator(){
Random random = ThreadLocalRandom.current();
byte[] r = new byte[32]; //Means 2048 bit
random.nextBytes(r);
secret = Base64.getUrlEncoder().encodeToString(r);
}
public String getSecret() {
return secret;
}
}
Then I merely have to declare it as a BEAN in the config:
@Bean(name='secretGenerator')
public SecretGenerator secretGenerator() {
return new SecretGenerator();
}
Now, whenever I need a class to access it I include like so:
@Autowired
private SecretGenerator secretGenerator;
… and then call it in code.
public String getUsernameFromToken(String token) {
Claims claims = Jwts.parser().setSigningKey(secretGenerator.getSecret()).parseClaimsJws(token).getBody();
return claims.getSubject();
}
Simple.
Benefits
This can avoid session hijacking and token spoofing as it makes it impossible to get the ‘secret’ even if someone had access to the server.
This does not mean that a developer couldn’t maliciously echo it out in the code. But this illustrates that someone woulkd require access to the code to be able to bypass this security mechanism.
Drawbacks
As mentioned above, you can’t do SSO without storing this ‘secret’. The secret cannot be shared/passed so in order to use it across multiple application servers, one would have to store the secret (ie cache/db).