HardhatFoundry
30,000 USDC
View results
Submission Details
Severity: medium
Invalid

Malleable signature

Summary

The Nexus.sol smart contract is vulnerable to a replay attack. This attack allows an attacker to reuse previously signed transactions, enabling unauthorized and repetitive execution of the same transaction.

Vulnerability Details

The Nexus protocol relies on signatures to verify the authenticity and integrity of transactions. However, it lacks mechanisms to prevent the reuse of these signatures in subsequent transactions, making it susceptible to replay attacks. The protocol relies on Solady's SignatureCheckerLib to verify that the signature provided is valid.

The Solady's SignatureCheckerLib warns that the library does not check if a signature is non-malleable.

https://github.com/Vectorized/solady/blob/a34977e56cc1437b7ac07e6356261d2b303da686/src/utils/SignatureCheckerLib.sol#L23

/// WARNING! Do NOT use signatures as unique identifiers:
/// - Use a nonce in the digest to prevent replay attacks on the same contract.
/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts.
/// EIP-712 also enables readable signing of typed data for better user safety.
/// This implementation does NOT check if a signature is non-malleable.
library SignatureCheckerLib {

Here is the contracts/Nexus.sol::isValidSignature() function:

function isValidSignature(bytes32 hash, bytes calldata data) external view virtual override returns (bytes4) {
// First 20 bytes of data will be validator address and rest of the bytes is complete signature.
address validator = address(bytes20(data[0:20]));
require(_isValidatorInstalled(validator), InvalidModule(validator));
(bytes32 computeHash, bytes calldata truncatedSignature) = _erc1271HashForIsValidSignatureViaNestedEIP712(hash, data[20:]);
return IValidator(validator).isValidSignatureWithSender(msg.sender, computeHash, truncatedSignature);
}

which in turn calls contracts/modules/validators/K1Validator.sol::isValidSignatureWithSender() and contracts/modules/validators/K1Validator.sol::validateUserOp():

function isValidSignatureWithSender(address, bytes32 hash, bytes calldata data) external view returns (bytes4) {
address owner = smartAccountOwners[msg.sender];
// Validate the signature using SignatureCheckerLib
if (SignatureCheckerLib.isValidSignatureNowCalldata(owner, hash, data)) {
return ERC1271_MAGICVALUE;
}
if (SignatureCheckerLib.isValidSignatureNowCalldata(owner, MessageHashUtils.toEthSignedMessageHash(hash), data)) {
return ERC1271_MAGICVALUE;
}
return ERC1271_INVALID;
}
function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external view returns (uint256) {
address owner = smartAccountOwners[userOp.sender];
if (
owner.isValidSignatureNow(ECDSA.toEthSignedMessageHash(userOpHash), userOp.signature) ||
owner.isValidSignatureNow(userOpHash, userOp.signature)
) {
return VALIDATION_SUCCESS;
}
return VALIDATION_FAILED;
}

This one uses SignatureCheckerLib to verify the signature, but as this implementation does not check if a signature is non-malleable, and there are no mechanisms or checks to prevent a sig reply, it makes the contract vulnerable to replay attacks.

Impact

When a signature is malleable, it means that it is possible to produce another valid signature for the same message (which also means the same digest). Replayed transactions can trigger contract functions unintentionally, causing disruptions and potential financial loss and undermining the trust in the security and integrity of the Nexus system, potentially deterring users from adopting the platform.

Tools Used

Manual review.

Recommendations

Implement checks to ensure that the s value in the (r, s, v) signature is in the lower half order. This can prevent signature malleability.

Updates

Lead Judging Commences

0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-replay-attack-malleable

Valid medium, although all issues lack a little detail on some form of protocol specific impact here. See similar reference finding [here](https://github.com/sherlock-audit/2024-04-titles-judging/issues/279)

Appeal created

0xnevi Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Other
Assigned finding tags:

finding-replay-attack-malleable

Valid medium, although all issues lack a little detail on some form of protocol specific impact here. See similar reference finding [here](https://github.com/sherlock-audit/2024-04-titles-judging/issues/279)

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.