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

Unhandled failure in OffchainDNSResolver for invalid addresses in DNS records #221

Open
tinchoabbate opened this issue Mar 2, 2023 · 0 comments

Comments

@tinchoabbate
Copy link

I was just checking the newish OffchainDNSResolver contract, and there seems to be an unhandled failure in the OffchainDNSResolver when a user includes an invalid resolver address as part of their DNS record.

As far as I understand, the root problem is in the way OffchainDNSResolver::parseAndResolve attempts to parse the user-provided value to an address.
Whatever value is passed in the nameOrAddress parameter, as long as it starts with 0x, it will be passed down to the HexUtils::hexToAddress function. Where it will attempt to cast it to an Ethereum address. Internally, this function never checks whether the length of the supplied data is longer than an address. It just casts it to a bytes32 value, and then to address.

As an example, the string 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 would be considered to be the address 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00. This means that OffchainDNSResolver::parseRR would return a non-zero address (which is interpreted as a signal for a valid record found) and the name would try to be resolved calling the 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 account.

If the called account happens to be empty (most likely the case if the record was just set incorrectly due to a user's oversight), then execution is reverted with error "function returned an unexpected amount of data" instead of the more gracious CouldNotResolve(bytes) error. This is because the call to IERC165(dnsresolver).supportsInterface(...) is using the explicit cast to the IERC165 interface, which is always expecting a boolean in return - reverting otherwise.

Perhaps the code could be changed to fail earlier. Non-addresses shouldn't be silently parsed as addresses.

Once that's fixed, we'd be left with the scenario where the user sets a valid address in the record, but that address corresponds to a custom resolver that does not follow IERC165. If you want to support that case (which appears to be so, given this fallback-like staticcall), then instead of explicitly casting to IERC165 you might want to consider using the ERC165Checker lib or anything similar that does not revert, but instead allows you to explicitly handle errors when querying unsupported interfaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant