# fallback() function can bypass permission/auth checks imposed in execute()

Vault fallback() dispatches to installed plugins without permission checks, letting a prior owner's transfer plugin move vault NFTs after ownership transfer.

- Payout: Contest reward
- Severity: medium
- Program: Fractional
- Credited: bbrho
- Disclosed: 2022-09-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-07-fractional-findings/issues/47
- Library page: https://bugbountylibrary.com/r/c4%3A2022-07-fractional%3AM-09
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:auth-bypass

**Target:** Vault contract fallback() plugin dispatch
**Root cause:** fallback() forwards calls to installed plugin selectors with no caller permission check, unlike execute(); plugin auth requirements are not tracked per-plugin.
**Steps:**
1. Install a transfer plugin on the vault: `vaultProxy.install([transferTarget.ERC721TransferFrom.selector], [address(transferTarget)])`
2. Transfer vault ownership to Bob: `vaultProxy.transferOwnership(bob.addr)`
3. As original owner, call the vault with the plugin's calldata `data` (ERC721TransferFrom) via `address(vaultProxy).call(data)`
4. fallback() dispatches to the plugin without auth, moving the vault's NFT to Alice
**How found:** Compared fallback() dispatch against execute()'s permission checks and noted fallback assumes plugins are safe; wrote a Foundry test installing a transfer plugin then transferring ownership to demonstrate unauthorized NFT movement.
**Exploitation:** A prior owner (or owner who installed a malicious/misconfigured plugin) retains the ability to invoke plugin selectors through fallback() after transferring ownership, draining NFTs held by the vault to an arbitrary address without the new owner's consent.
**Insight:** When a contract has two entry paths to the same plugin/call surface, diff their auth checks; fallback dispatch that trusts install-time safety is a classic gap when ownership or plugin config can change later.
