1
votes

I am using Guava LoadingCache for caching auth requests for the external storage. The key is the object Auth:

public class Auth {
    private String username;
    private String password;
    public boolean equals(Object o);
}

and the response is HttpStatus, OK or FORBIDDEN.

When the password for username in external storage is changed, I need to remove cache record for username, but the problem is that the passwords storing only as a hash, not the original value, so I can't just construct new Auth object for invalidation, like:

cache.invalidate(new Auth(<username>, <password>));

How can I invalidate cache record, using only username value?

4
Why not use Auth as the key?mfulton26
Cause I don't know the original password, only the stored MD5 hash. And in the cache I have Auth with the original password, so they not equal.mv200580
I feel silly, what I meant to ask is, "Why not use username as the key"?mfulton26
And how it must work? For example, I got two records in cache: Auth(user1, password1) = OK and Auth(user1, password2) = FORBIDDEN. So password1 is correct, and password2 is incorrect. If I'll receive more one request with Auth(user1, password2) , I just return FORBIDDEN without quering the external storage. If I will use only username as a key, I will need to query the storage every time I receive request.mv200580

4 Answers

4
votes

For example, I got two records in cache: Auth(user1, password1) = OK and Auth(user1, password2) = FORBIDDEN. So password1 is correct, and password2 is incorrect. If I'll receive more one request with Auth(user1, password2) , I just return FORBIDDEN without querying the external storage.

The problem with this is that you'll hardly ever see Auth(user1, password2) (i.e., an invalid pair) again. A legitimate user can make a mistake and they might repeat exactly the same mistake, but that's rare. An attacker won't waste time with repeating a failed combination. So such an entry is just wasted memory.

Storing user as the key and password or hashedPassword as the value should work well and in case of a hit it will save you the external storage access: all you need is a comparison and hashing.

While I don't think that your problem makes sense, I try to propose a solution: Invalidating by a part of a key is impossible, but you can instead keep a set of all users having changed their password recently (e.g., in the last 24 hours). If you set expireAfterWrite to a smaller value, then you can be sure that an invalid Auth can be detected by consulting the set.

Note that protecting passwords by MD5 only is very week. There are much better algorithms like bcrypt or bcrypt, designed for slowing down password cracking.

1
votes

How about implementing a RemovalListener that executes on an eviction and removes the key e.g. username from a separate data structure that is based on key value pairs.

1
votes

What about

  • walk through the cache keys
  • look for changed user
  • invalidate the key

The second option is using user as the cache key and the password hash as the value instead of the caching of the service response

0
votes

In my opinion caching password instead hash is not good practice. The key could be only username or username and hash.