KatanaGovernance may specify a configurable expiry data for authorized accounts, however due to an invalid comparator, expired authorizations remain active for longer than intended:
/**
* @dev Checks if an account is authorized.
* @param account The address of the account to check authorization for.
* @return A boolean indicating whether the account is authorized or not.
*/
function _isAuthorized(Permission storage $, address account) private view returns (bool) {
uint256 expiry = $.whitelistUntil;
if (expiry == UNAUTHORIZED) return false;
@> if (expiry == AUTHORIZED || block.timestamp > expiry) return true;
return $.allowed[account];
}
Notice here that if the expiry is neither configured to UNAUTHORIZED nor AUTHORIZED, it will be compared against the block.timestamp:
if (expiry == AUTHORIZED || block.timestamp > expiry) return true;
Here, we see that if the block.timestamp exceeds the configured expiry, it will continue to be interpreted as authorized.
Lines of code
https://github.com/ronin-chain/katana-operation-contracts/blob/27f9d28e00958bf3494fa405a8a5acdcd5ecdc5d/src/governance/KatanaGovernance.sol#L378
Vulnerability details
Proof of Concept
KatanaGovernance
may specify a configurableexpiry
data for authorizedaccount
s, however due to an invalid comparator, expired authorizations remain active for longer than intended:Notice here that if the
expiry
is neither configured toUNAUTHORIZED
norAUTHORIZED
, it will be compared against theblock.timestamp
:Here, we see that if the
block.timestamp
exceeds the configuredexpiry
, it will continue to be interpreted as authorized.Recommended Mitigation Steps
Invert the comparison:
Assessed type
Invalid Validation