Use redis cache in get_approx_account_lockouts_from_login_attempts#250
Conversation
|
@irkonikovich The tests are not passing. I also passed this through claude and got the following output, please take a look. PR #250 Review: Use redis cache in get_approx_account_lockouts_from_login_attempts I found several significant issues with this PR: Critical Issues
The test test_approx_account_lockout_uses_redis_cache asserts that the cached value is None:
But based on the implementation, after calling get_approx_account_lockouts_from_login_attempts(), the value should be cached. The test is verifying that caching is not working, which is the opposite of what the test name implies. This should be:
The test uses get_redis_connection() but never imports it: from defender.data import get_approx_account_lockouts_from_login_attempts, get_approx_lockouts_cache_key Design Concerns
When new login attempts are stored via store_login_attempt(), the cache is never invalidated. This creates a stale data problem:
The
The cache TTL is set to ACCESS_ATTEMPT_EXPIRATION * 60 * 60 seconds (default is likely hours). Combined with no invalidation, this means stale data could persist for a very long time. SummaryThis PR is not ready to merge. The test would fail to run (missing import) and is testing the wrong behavior. More importantly, the lack of cache invalidation could lead to security issues where attackers receive shorter lockout cooloff periods than intended. |
kencochrane
left a comment
There was a problem hiding this comment.
Look close, just a comment
|
|
||
| redis_cache_key = get_approx_lockouts_cache_key(ip_address, None) | ||
|
|
||
| if redis_cache_key is not None: |
There was a problem hiding this comment.
This will always return True because get_approx_lockouts_cache_key() always returns a string. So this is redundant. Is there a reason why you are doing this check?
There was a problem hiding this comment.
You're right. I was looking at too many things at once.
This if is only valid where get it from the cache, not when I generate the key. It's a copy-paste error.
I will remove it, thank you!
|
|
||
| redis_cache_key = get_approx_lockouts_cache_key(ip_address, username) | ||
|
|
||
| if redis_cache_key is not None: |
There was a problem hiding this comment.
This will always return True because get_approx_lockouts_cache_key() always returns a string. So this is redundant. Is there a reason why you are doing this check?
|
|
||
| redis_cache_key = get_approx_lockouts_cache_key(None, username) | ||
|
|
||
| if redis_cache_key is not None: |
There was a problem hiding this comment.
This will always return True because get_approx_lockouts_cache_key() always returns a string. So this is redundant. Is there a reason why you are doing this check?
No description provided.