Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature Malleability in ERC721 Permit #145

Closed
code423n4 opened this issue May 8, 2023 · 5 comments
Closed

Signature Malleability in ERC721 Permit #145

code423n4 opened this issue May 8, 2023 · 5 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working edited-by-warden sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") unsatisfactory does not satisfy C4 submission criteria; not eligible for awards

Comments

@code423n4
Copy link
Contributor

code423n4 commented May 8, 2023

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/fc70fb9d05b13aee2b44be2cb652478535a90edd/ajna-core/src/base/PermitERC721.sol#L97-L110

Vulnerability details

Impact

Replay attacks are possible thanks to signature malleability

Proof of Concept

The ecrecover EVM opcode has a limitation that allows for non-unique signatures, which means that different signatures can produce the same output.

According to EIP-2, any transaction signatures with an s-value greater than secp256k1n/2 are considered invalid. However, validating such signatures by passing them to the _verify function is still possible.

To create a malleable signature, one can flip the s value from s to secp256k1n - s and also flip the v value (27 -> 28, 28 -> 27). Surprisingly, the resulting signature would still be valid.

https://github.com/code-423n4/2023-05-ajna/blob/fc70fb9d05b13aee2b44be2cb652478535a90edd/ajna-core/src/base/PermitERC721.sol#L97-L110

    address owner = ownerOf(tokenId_);
        require(spender_ != owner, "ERC721Permit: approval to current owner");

        if (Address.isContract(owner)) {
            // bytes4(keccak256("isValidSignature(bytes32,bytes)") == 0x1626ba7e
            require(
                IERC1271(owner).isValidSignature(digest, abi.encodePacked(r_, s_, v_)) == 0x1626ba7e,
                "ajna/nft-unauthorized"
            );
        } else {
            address recoveredAddress = ecrecover(digest, v_, r_, s_);
            require(recoveredAddress != address(0), "ajna/nft-invalid-signature");
            require(recoveredAddress == owner, "ajna/nft-unauthorized");
        }

Even though ERC721 permit could be out of scope, I've confirmed the issue with the sponsor and after discussing with the C4 team we agreed to fill it in: since the scope section in the audit repo isn't 100% clear here. So ultimately this will end up being a call the judge makes.

Tools Used

Manual Review
Discussion/confirmation with the Ajna Protocol team.

Recommended Mitigation Steps

To address this issue, OpenZeppelin has taken measures to handle malleable signatures. You can find more information on how they tackled this problem at this GitHub link: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol#L125.

Assessed type

Access Control

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels May 8, 2023
code423n4 added a commit that referenced this issue May 8, 2023
@c4-sponsor
Copy link

MikeHathaway marked the issue as sponsor confirmed

@c4-sponsor c4-sponsor added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label May 19, 2023
@c4-judge
Copy link
Contributor

Picodes marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label May 30, 2023
@c4-judge c4-judge added unsatisfactory does not satisfy C4 submission criteria; not eligible for awards and removed satisfactory satisfies C4 submission criteria; eligible for awards labels May 30, 2023
@c4-judge
Copy link
Contributor

Picodes marked the issue as unsatisfactory:
Out of scope

@Picodes
Copy link

Picodes commented May 30, 2023

Unfortunately, the contract was clearly out of scope in the README.md of the contest. Although the finding is technically valid we can't include it in the price pool as audits are priced according to the number of LOC in scope. So it's up to the sponsor to reward this independantly.

@Picodes
Copy link

Picodes commented May 31, 2023

@MikeHathaway regarding #147, #141, #143 and this issue please see my comment above regarding out of scope findings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working edited-by-warden sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") unsatisfactory does not satisfy C4 submission criteria; not eligible for awards
Projects
None yet
Development

No branches or pull requests

4 participants