The WeatherNft::performUpkeep
function allows any external address to call it with a valid tokenId, triggering a new Chainlink Functions request and consuming LINK from the Automation subscription balance. There are no access controls or heartbeat checks to restrict how frequently this can be called. An attacker can repeatedly call performUpkeep
to rapidly drain all LINK from the subscription, causing denial of service for legitimate users and disabling the NFT's automated weather updates.
Unrestricted LINK Drain
Anyone can call performUpkeep
with the tokenId of an NFT, regardless of whether the heartbeat interval has passed or whether the caller is a trusted automation agent.
Each call triggers a Chainlink Functions request and consumes LINK from the Automation subscription balance.
Repeated or automated calls will quickly exhaust the LINK balance, breaking automated updates for all NFTs in the project.
Likelihood:
Any attacker or bot can repeatedly call performUpkeep
with the same tokenId, as often as they want.
This attack does not require any special privileges or timing, making it trivial to exploit on a large scale.
Impact:
All LINK in the project's Chainlink Automation subscription can be drained, incurring significant financial loss.
Legitimate users lose automated weather updates for their NFTs, and the service is effectively disabled until more LINK is deposited.
This PoC demonstrates an attacker can drain LINK by repeatedly calling performUpkeep
with the same tokenId, even if the heartbeat interval has not elapsed.
A legitimate user mints a Weather NFT, registering for automated weather updates. This process funds the Chainlink Automation subscription with LINK.
The attacker waits for the NFT to be minted and retrieves the tokenId.
The attacker then repeatedly calls performUpkeep
with the same tokenId, simulating hundreds of rapid weather update requests.
Each call to performUpkeep
triggers a Chainlink Functions request and consumes LINK from the project's Automation subscription balance.
Because there are no heartbeat checks or access controls, the attacker is able to continuously drain the LINK balance, eventually exhausting all funds allocated for automation.
Once the LINK balance is depleted, legitimate users lose the ability to receive automated weather updates for their NFTs, and the automation feature is effectively disabled until the subscription is refilled.
Manual Review
Foundry Unit Testing
Enforce a Heartbeat Check
Require that performUpkeep
can only be executed if the heartbeat interval has elapsed since the last successful weather update. This prevents repeated or premature calls from consuming LINK unnecessarily.
Refine Access Controls for Automated and Manual Updates
Differentiate between NFTs registered with Chainlink Automation (having a nonzero upkeepId
) and those without.
For automated updates (info.upkeepId != 0
), allow only the Keeper Registry contract to call.
For manual updates (info.upkeepId == 0
), allow only the NFT owner to call.
The `performUpkeep` function should be called by the Chainlink keepers or owners of the NFT. But there is no access control and anyone can call the function. This leads to malicious consumption of the user's LINK deposit.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.