ENS Contest - bin2chen's results

Decentralised naming for web3

General Information

Platform: Code4rena

Start Date: 14/04/2023

Pot Size: $90,500 USDC

Total HM: 7

Participants: 59

Period: 14 days

Judge: LSDan

Total Solo HM: 3

Id: 232

League: ETH

ENS

Findings Distribution

Researcher Performance

Rank: 17/59

Findings: 2

Award: $754.35

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: hihen

Also found by: Parad0x, bin2chen, chaduke, eierina, nobody2018, rvierdiiev

Labels

bug
2 (Med Risk)
satisfactory
edited-by-warden
duplicate-246

Awards

694.5552 USDC - $694.56

External Links

Lines of code

https://github.com/code-423n4/2023-04-ens/blob/45ea10bacb2a398e14d711fe28d1738271cd7640/contracts/dnsregistrar/RecordParser.sol#L34

Vulnerability details

Impact

readKeyValue() Possible incorrect read value

Proof of Concept

readKeyValue() is used to read the key and value values and return the offset nextOffset of the next key-value pair

The code is as follows:

    function readKeyValue(
        bytes memory input,
        uint256 offset,
        uint256 len
    )
        internal
        pure
        returns (bytes memory key, bytes memory value, uint256 nextOffset)
    {
        uint256 separator = input.find(offset, len, "=");
        if (separator == type(uint256).max) {
            return ("", "", type(uint256).max);
        }

        uint256 terminator = input.find(
            separator,
            len + offset - separator,
            " "
        );
        if (terminator == type(uint256).max) {
            terminator = input.length;  //<--------@audit Wrong use `input.length`, should use `offset+len`
        }

        key = input.substring(offset, separator - offset);
        value = input.substring(separator + 1, terminator - separator - 1);
        nextOffset = terminator + 1;
    }

As the above code comment, when terminator cannot be found, the wrong setting terminator = input.length, should use terminator= offset + len

Because input is limited to find in the length of len, the current protocol is to reuse bytes to find in a specific range in many places

For example:

input contains three blocks: flag, text, signdata, [] which represents the length of each block, we want to get the second block text inside the key/value

input = [4]flag|[3]a=b|[8]signdata

At this point if we execute readKeyValue(input,6,3), we expect to get key=a and value=b The current implementation will get key=a and value=bsigndata

Tools Used

    function readKeyValue(
        bytes memory input,
        uint256 offset,
        uint256 len
    )
        internal
        pure
        returns (bytes memory key, bytes memory value, uint256 nextOffset)
    {
        uint256 separator = input.find(offset, len, "=");
        if (separator == type(uint256).max) {
            return ("", "", type(uint256).max);
        }

        uint256 terminator = input.find(
            separator,
            len + offset - separator,
            " "
        );
        if (terminator == type(uint256).max) {
-           terminator = input.length;  
+           terminator= offset + len;
        }

        key = input.substring(offset, separator - offset);
        value = input.substring(separator + 1, terminator - separator - 1);
        nextOffset = terminator + 1;
    }

#0 - c4-pre-sort

2023-05-01T10:38:51Z

thereksfour marked the issue as duplicate of #246

#1 - c4-judge

2023-05-08T14:44:45Z

dmvt marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter