Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as primary issue
AustinGreen marked the issue as sponsor disputed
Roles must be explicitly revoked or else the expiration hasn't taken effect. This is how the system is intended to be used.
gzeon-c4 marked the issue as unsatisfactory: Invalid
Hi @gzeon-c4,
I want to know your thoughts about this one from a security perspective. I don't agree with the sponsor's point here.
Some issues could be considered an improvement design but this design simply introduce different attack vectors.
The system is designed to be dynamic as possible, when instance owners set new policyHolders with different users they set the expiration role and they except that it will expire at that time, but due to the design implemented the owner may not revoke the policyHolder roles. Consider the following scenario:
setRoleHolder
and are set to be expired at the time the action gets executed.However, due to the design here, the users will keep their permission until it is noticed by the llama. This is clearly not an intended behavior or even excepted by the users.
I know it's clearly design, my point is that this is not a secure design. Have you thought about front-run attacks that will be introduced based on this design? Does the scenario I have mentioned above is applicable?
With total respect, I feel like you are not adding more context from security PoV about why my attack vectors are not valid. either for this one or other issues. This will help me improve my self when I get feedback about what I miss. Thanks!
I know it's clearly design, my point is that this is not a secure design. Have you thought about front-run attacks that will be introduced based on this design? Does the scenario I have mentioned above is applicable?
With total respect, I feel like you are not adding more context from security PoV about why my attack vectors are not valid. either for this one or other issues. This will help me improve my self when I get feedback about what I miss. Thanks!
Just like a timelock, the role revocation is not automatic after the delay, but can be executed at anytime after the delay. If the user failed to run an offchain monitoring script to execute the revocation it would be considered as an user error and is out-of-scope. The protocol defines the expiry
like a timelock delay, not a hard expiration, as also documented here:
https://github.com/code-423n4/2023-06-llama/blob/9d422c264b57657098c2784aa951852cad32e01c/src/LlamaPolicy.sol#L436-L438
The policy contract has an invariant that even when a role is expired, i.e.
block.timestamp > expiration
, that role is still active until explicitly revoked withrevokeExpiredRole
.
There are certainly trade-off with every design, but it's not a security issue just because one misunderstood a well documented behavior.
Lines of code
https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaCore.sol#L516 https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaCore.sol#L565 https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaCore.sol#L576
Vulnerability details
Impact
The functions
_createAction
,_castApproval
, andcastDisapproval
doesn't check if thepolicyHolder
roles is expired usingisRoleExpired
.The system already has a function to remove expired roles at
LlamaPolicy::revokeExpiredRole
but this function must be called manually and by someone who monitor the role. This design introduce 2 impacts:revokeExpiredRole
and use his privilege permission even it's expired.Proof of Concept
_createAction
,_castApproval
, andcastDisapproval
doesn't check if the role is expired:https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaCore.sol#L516
https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaCore.sol#L565
https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaCore.sol#L576
revokeExpiredRole
which should be called manually. https://github.com/code-423n4/2023-06-llama/blob/main/src/LlamaPolicy.sol#L217Tools Used
Manual
Recommended Mitigation Steps
The functions mentioned above should add the check below:
You can also call
revokeExpiredRole
to revoke the role without reverting and usereturn
to not make any further changes.Assessed type
Context