The Graph L2 bridge contest - zzzitron's results

A protocol for indexing and querying blockchain data.

General Information

Platform: Code4rena

Start Date: 07/10/2022

Pot Size: $50,000 USDC

Total HM: 4

Participants: 62

Period: 5 days

Judge: 0xean

Total Solo HM: 2

Id: 169

League: ETH

The Graph

Findings Distribution

Researcher Performance

Rank: 31/62

Findings: 1

Award: $50.28

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

50.2765 USDC - $50.28

Labels

bug
QA (Quality Assurance)

External Links

Lines of code

https://github.com/code-423n4/2022-10-thegraph/blob/7ea88cc41f17f2d49961aafec7ebe72daeaad3f9/contracts/gateway/L1GraphTokenGateway.sol#L212-L214 https://github.com/code-423n4/2022-10-thegraph/blob/7ea88cc41f17f2d49961aafec7ebe72daeaad3f9/contracts/gateway/L1GraphTokenGateway.sol#L152-L157

Vulnerability details

Impact

If l1Router is added to the callhookWhitelist, anybody who is using the router can use the call hook. There is no safe guard against adding l1Router to the callhookWhitelist

Proof of Concept

In the L1GraphTokenGateway::outboundTransfer function, it checks whether the msg.sender is in the whitelist. If the msg.sender is whitelisted, it allows to use the callhook on the L2 side. When someone is using the router to send graph token, the transaction will always have the router as msg.sender. Therefore, if the router is added as a callhookWhitelist, it allows anybody who uses the router to use the callhook, which is not the intended usage based on the specification.

In the L1GraphTokenGateway::addToCallhookWhitelist (line 152), it does not check the _newWhitelisted against the l1Router, therefore the l1Router.

// L1GraphTokenGateway
// outboundTransfer

212                 (from, maxSubmissionCost, extraData) = parseOutboundData(_data);
213                 require(
214                     extraData.length == 0 || callhookWhitelist[msg.sender] == true,
// L1GraphTokenGateway

152     function addToCallhookWhitelist(address _newWhitelisted) external onlyGovernor {
153         require(_newWhitelisted != address(0), "INVALID_ADDRESS");
154         require(!callhookWhitelist[_newWhitelisted], "ALREADY_WHITELISTED");
155         callhookWhitelist[_newWhitelisted] = true;
156         emit AddedToCallhookWhitelist(_newWhitelisted);
157     }

Tools Used

Manual review

Add the check require(_newWhitelisted != l1Router);. To be really sure, when l1Router is updated, check whether l1Router is in the whitelist.

<!-- zzzitron M00 -->

#0 - trust1995

2022-10-12T21:28:01Z

Seems like a very unlikely mistake to make, to add router to the whitelist. The project mentioned only very few contracts like Rewarder would get in.

#1 - 0xean

2022-10-16T16:36:32Z

I think this comes down to QA, there could be any number of potential addresses that would allow someone to do something that is unexpected, which is why the whitelist exists.

So this issue seems to boil down to if address X is accidentally added to the whitelist, address X can use the hook.... well yes, that is true.

#2 - pcarranzav

2022-10-19T16:38:15Z

Agree this is more QA than Med, but good find nonetheless

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