The function deployProxyAndDistributeBySignature
in the ProxyFactory
contract may lead to unintended fund distributions due to the reuse of old signatures with new Distribution.sol
contracts. Without sufficient restrictions on the signature's usage, an attacker can exploit this to deploy a new proxy and divert the funds to himself in new Distributor.sol
contracts.
The function uses the following digest for ECDSA signature verification:
The digest can be recreated by a malicious user and exploited with a replay attack under the right circumstances. The vulnerabilities of the current digests are that there are no deadlines for how long the digests are valid. It also doesn’t distinguish which version of the implementation
contract the digests use.
This means that the digests will be valid for any time in the future and for any new implementation contracts.
An organizer holds an annual contest. They ask the owner
to help setContest
and then send the ERC20 tokens to the to-be proxy address in preparation for the contest.
The malicious attacker participates in the contest and wins.
When the contest has ended, the organizer deploys a proxy contract (through their signature) and distribute the funds from the proxy contract to the winners
array (including the malicious attacker) using the function deployProxyAndDistributeBySignature
.
So far, it is working as the contract is intended to work.
One year later, the owner
has deployed a new implementation
contract.
The organizer decides to hold their annual contest once again. They ask the owner
to help set up the contest once again by calling setContest
using the same contestId
but this time with the new implementation
contract. The organizer again sends the ERC20 tokens to the to-be proxy address in preparation for the contest. The proxy address will be another one since the implementation contract is new:
And here's the attack. Immediately after the contest ends, a malicious attacker will be the first to call deployProxyAndDistributeBySignature
with the signature and digest used for the last competition:
The malicious attacker will pass all the checks in deployProxyAndDistributeBySignature
since the digest and signature will still correctly recover the organizer's address as per below. It will also pass the saltToCloseTime
checks since the contest has been set (albeit with the new implementation address).
Lastly, the malicious attacker will have successfully deployed a new proxy contract and distributed the funds per the outcome of the old contest instead of the new one.
Malicious actors can benefit from the reuse of signatures, directing funds for distribution to themselves and/or others per an old competition result.
The severity of this issue is high, as a malicious attacker could divert funds from the intended recipients.
The likelihood of performing this attack is low. It would require a new Distributor.sol
contract to be deployed where a new contest is set with the same contestId
as in the old Distributor.sol
contract.
Manual Review.
Include a deadline and the contract address of the current implementation
in the digest to make the signature time-sensitive and specific to the implementation:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.