Submitted on Nov 30th 2023 at 09:33:15 UTC by @EricTee for Boost | DeGate
Report ID: #26286
Report type: Smart Contract
Report severity: Insight
Impacts:
- Signature Validation Bypass
In https://github.com/degatedev/protocols/blob/degate_mainnet/packages/loopring_v3/contracts/lib/SignatureUtil.sol#L32-L51
:
function verifySignatures(
bytes32 signHash,
address[] memory signers,
bytes[] memory signatures
)
internal
view
returns (bool)
{
require(signers.length == signatures.length, "BAD_SIGNATURE_DATA");
address lastSigner;
for (uint i = 0; i < signers.length; i++) {
require(signers[i] > lastSigner, "INVALID_SIGNERS_ORDER");
lastSigner = signers[i];
if (!verifySignature(signHash, signers[i], signatures[i])) {
return false;
}
}
return true;
}
There is a potential signature validation bypass scenario happens in the above code, since there is no check that require(signers.length != 0)
, if an attacker passes in empty array of signers
and signatures
values, he can bypass the for loop. As a result, the function will directly return true
. Though this function is not used anyway in the protocol yet, but I think the awareness should be raised to the protocol team in case this function is implemented in the future.
Potential Signature Validation Bypass
Difficulty to Exploit: Easy Weakness: Signature Validation Bypass CVSS2 Score: NA
Consider adding the check require(signers.length != 0, "BAD_SIGNATURE_DATA");
:
function verifySignatures(
bytes32 signHash,
address[] memory signers,
bytes[] memory signatures
)
internal
view
returns (bool)
{
++ require(signers.length != 0, "BAD_SIGNATURE_DATA");
require(signers.length == signatures.length, "BAD_SIGNATURE_DATA");
address lastSigner;
for (uint i = 0; i < signers.length; i++) {
require(signers[i] > lastSigner, "INVALID_SIGNERS_ORDER");
lastSigner = signers[i];
if (!verifySignature(signHash, signers[i], signatures[i])) {
return false;
}
}
return true;
}
NA
NA