Submitted by zhaojie
Recover a cached value that has timed out, and a malicious user or contract can exploit this bug to fool other users or cause other unknown problems.
The LocalCache#set_expire function does not check whether the key has expired when setting a timeout:
As we can see from the above code, the set_expire function will first call maybe_clear_expired. The function maybe_* is called, so it wont necessarily delete keys that have expired. This function will not clean up expired keys until gc count reaches a certain value.
Therefore, if there are keys that have expired, they are still queried from storages and then reset the expiration time. In other words, the set_expire function can cause an expired key to be reactivated.
Lets look at another function, LocalCache#get:
The get function returns None if it finds that key has expired; this results in inconsistency of cached data.
In this way, when a key value (such as balance signature or debt) has expired, the attacker declares that the value no longer exists. The user is then asked to take some action, so the victim queries LocalCache#get and then finds that the value indeed no longer exists. The problem is that an attacker can use set_expire to restore this value.
Another attack scenario is:
The key value (such as an nft) that the developer thinks has expired no longer exists. However, a malicious user can make this value expire indefinitely if set_expire can be called.
Tips:
LocalCache#set does not have this problem. LocalCache#set will call Storage#set, which will first call self.remove to remove the existing key.
VS Code
kvinwang (Phala) confirmed, but disagreed with severity and commented:
Lambda (judge) decreased severity to Medium and commented:
DadeKuma (warden) commented:
zhaojie (warden) commented:
DadeKuma (warden) commented:
zhaojie (warden) commented:
Lambda (judge) commented:
