Post Mortem: NFTXMarketplace0xZap Vulnerability
This is a brief overview of the recent vulnerability reported through our bug bounty program.
*Note this post has been updated on 30th September 2022 to include the full details of the post mortem.
Incident Summary
The purpose of the NFTXMarketplaceZap is to facilitate buying and selling vault tokens in conjunction with minting, redeeming, and swapping on NFTX. Last month the NFTX team wrote and deployed a new contract called NFTXMarketplace0xZap
which differed from the previous zap contract by sourcing liquidity from 0xProtocol instead of just Sushiswap. On September 5th, the NFTX team switched over to the new NFTXMarketplace0xZap, and users began interacting with it when buying, selling, and swapping NFTs on the NFTX dapp.
On September 13th, p0n1 from SECBIT Labs, submitted a detailed bug report via email to [email protected] explaining that anyone who approved the NFTXMarketplace0xZap was at risk of having NFTs stolen from whichever NFT contracts they approved. The estimated potential loss was over 300 ETH in NFTs. Upon receiving the report, the NFTX team paused minting, redeeming, and swapping across all vaults to negate the possibility of an exploit and allow time to investigate and deploy a fix.
On September 14th, a new vault contract was deployed and staged as an upgrade via the NFTX DAO. The unpause functions were also staged to follow after the upgrade. On September 15th, the vault upgrade was enacted on the DAO, followed by the unpause calls, bringing the NFTX protocol back online for regular usage.
Impact
Fortunately, no assets were lost during the incident, and no assets remain at risk from the vulnerability. There was no activity during the pause, so anyone staking inventory or liquidity missed out on yield opportunities during that time.
Attack Vector
NFTXMarketplace0xZap
has an internal function called _fillQuote
that allows arbitrary calls. This function is called by the mintAndSell721
, buyAndSwap721
, buyAndRedeem
, and mintAndSell1155
functions, allowing the final swapTarget
and swapCallData
parameters to be specified by the caller.
As a result, an attacker could construct arbitrary parameters to execute arbitrary code in the name of the NFTXMarketplace0xZap
contract, enabling two possible attacks:
- Transferring any assets held in the
NFTXMarketplace0xZap
contract. - Transferring any assets authorized to the
NFTXMarketplace0xZap
contract.
Solution
As a fix, the NFTX team deployed a new NFTXVaultUpgradeable
contract as an upgrade for all NFTX vaults. This new vault contract includes a checkAddressOnDenyList
function which gets called by mintTo
, redeemTo
, and swapTo
, blocking execution of any calls originating from the vulnerable NFTXMarketplace0xZap
. This ensures that the previously deployed NFTXMarketplace0xZap
cannot be exploited by an attacker.
A new NFTXMarketplace0xZap
contract is being prepared for an audit and has been updated since learning about the vulnerability. The update involved removing the ability for a frontend client to provide the 0x integration swapTarget and instead set the address immutably on contract creation. This swapTarget sets the address reference that will handle the fill request and should always point to a 0x proxy contract.
This resolved the potential exploit threat, and we additionally implemented pausable logic to the contract to allow for the zap processes to be halted, rather than requiring an entire protocol halt which was required this time.
Event Timeline
- Aug-12-2022 07:55:32 AM +UTC —
NFTXMarketplace0xZap
was deployed - https://etherscan.io/tx/0xbc04919e259599d754011bddd52ef03c74c9f4c4fff160cb3fca3841eef3d0a3 - Sep-05-2022 12:14:21 PM +UTC — NFTX frontend routed all buy/sell/swap through the new zap (approximately 600 transactions)
- Sep-13-2022 18:16:00 PM +UTC — p0n1 contacted NFTX through Twitter DMs notifying us that a critical bug report had been sent to [email protected] with regards to the
NFTXMarketplace0xZap
- Sep-13-2022 19:05:24 PM +UTC — NFTX reviewed the report and confirmed by pausing the mint, redeem, swap actions on the vault factory to negate the vulnerability and any exploit occurring.
- https://etherscan.io/tx/0x65cb6d7c1493a730776d28362cd0581152aee3a7667f1ad847acb0872c11bec8
- https://etherscan.io/tx/0xdcd38b866b3952c44739bd6633fe8441be0f02db27e3a25fab1c33f1a2f15f5d
- https://etherscan.io/tx/0x6b89f73e0f4cca7b0dc22c9fb58fe1b4b57ae295b56a2a35e887e82c39863f70 - Sep-13-2022 19:18:00 PM +UTC — NFTX added status page message/site banner/tweet/discord update that the protocol was paused while investigation took place.
- Sep-14-2022 17:20:00 PM +UTC —A vault contract upgrade was staged (via DAO) to include a deny list function with the
NFTXMarketplace0xZap
address, fixing the vulnerability. - Sep-14-2022 20:11:00 PM +UTC —The unpause transactions were staged (via DAO) to restart the protocol.
- Sep-15-2022 17:20:00 PM +UTC —The vault upgrade vote was enacted (including the deny list).
- Sep-15-2022 22:15:00 PM +UTC —The unpause votes were enacted (enabling regular protocol usage).
Takeaway
The primary takeaway of this incident for the NFTX team is that future periphery smart contracts must be treated with the same caution as core smart contracts, especially when they receive authorization of users’ assets. Going forward, any periphery contracts will be audited before deployment, including the updated NFTXMarketplace0xZap
contract which is being prepared for audit now.
Next Steps
While the only risk for the NFTXMarketplace0xZap
is if it is used with the vault factory contract (which it can no longer do due to the hardcoded deny list) we believe it is best practice to revoke any access the NFTXMarketplace0xZap
contract has to your NFTs if they are not to be of use.
- Go to https://revoke.cash/
- Connect your account
- Find any mentions of
0xbbc53022Af15Bb973AD906577c84784c47C14371
- Click on the revoke button