ENS contest - Lambda's results

Decentralised naming for wallets, websites, & more.

General Information

Platform: Code4rena

Start Date: 12/07/2022

Pot Size: $75,000 USDC

Total HM: 16

Participants: 100

Period: 7 days

Judge: LSDan

Total Solo HM: 7

Id: 145

League: ETH

ENS

Findings Distribution

Researcher Performance

Rank: 15/100

Findings: 3

Award: $1,056.57

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: GimelSec

Also found by: Lambda, zzzitron

Labels

bug
duplicate
2 (Med Risk)
sponsor confirmed
dnssec

Awards

937.2294 USDC - $937.23

External Links

Lines of code

https://github.com/code-423n4/2022-07-ens/blob/04539b27307abd65068b96dd20fc686b451bf9fc/contracts/dnssec-oracle/DNSSECImpl.sol#L126 https://github.com/code-423n4/2022-07-ens/blob/04539b27307abd65068b96dd20fc686b451bf9fc/contracts/dnssec-oracle/RRUtils.sol#L267

Vulnerability details

Impact

RRUtils.serialNumberGte casts the passed uint32 to an int32 before doing the calculation. This cast can overflow, resulting in negative values, which invalidates the calculation and results in RRSet that are valid but cannot be validated.

Proof Of Concept

An RRSet has an expiration timestamp of 2147483648 (Tue Jan 19 2038 03:14:08 GMT+0000). On Jan 18 2038 (timestamp 2147382000), the RRSet is validated. Inside serialNumberGte, we have:

int32(2147483648) - int32(2147382000) = -2147483648 - 2147382000

This causes a reversion.

Although it is stated, the implementation does not actually implement RFC1982, where comparison is defined as:

s1 is said to be less than s2 if, and only if, s1 is not equal to s2, and (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1))

Furthermore, it is stated that "Arithmetic and comparisons applied to i1 and i2 use ordinary unbounded integer arithmetic." which of course is not the case for Soildity.

So you could either actually implement RFC1982 (incorporating bounded arithmetic in Solidity) or use a normal comparison.

#0 - Arachnid

2022-07-28T22:30:09Z

This is a bug - we should be using an unchecked block - but suggest that the severity is QA, since it doesn't apply until 2038 at the earliest and the contract is upgradeable.

#1 - Arachnid

2022-07-28T22:30:56Z

RE RFC1982, see my comment on #211.

#2 - dmvt

2022-08-04T21:09:35Z

Duplicate of #211

#0 - jefflau

2022-08-01T10:10:44Z

In setUpgradeContract, the variable _upgradeAddress could be used for the three calls on line 139 - 141 (https://github.com/code-423n4/2022-07-ens/blob/1772ac3d16c8e84bb9c1e02a0c4e321cd6f5652b/contracts/wrapper/NameWrapper.sol#L139) instead of always reading upgradeContract from memory.

It's reading from storage to get the value it currently is, not the value passed it, which is why the variables is underscored.

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