# Cross-chain message authentication can be bypassed, allowing an attacker to disrupt the state of vaults

XProvider's onlySource modifier accepts zero-address sender when origin domain is untrusted, letting anyone spoof Connext messages and corrupt vault allocations.

- Payout: Contest reward
- Severity: high
- Program: Derby
- Credited: Jeiwan
- Disclosed: 2022-10-17
- Write-up quality: 8/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/309
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AH-6
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:sherlock sev:high tech:evm technique:chained technique:source-review vuln:access-control vuln:auth-bypass vuln:oracle-manipulation

**Target:** XProvider cross-chain receiver contract (Connext IXReceiver)
**Root cause:** onlySource checks _originSender == trustedRemoteConnext[_origin] but never verifies trustedRemoteConnext[_origin] is non-zero; Connext's fast path passes address(0) as originSender, so any origin domain not configured in the mapping matches the zero default.
**Steps:**
1. Identify a Connext-supported domain not configured in Derby's trustedRemoteConnext (e.g. Gnosis Chain).
2. Send a Connext message from that domain to XProvider with arbitrary callData targeting an onlySelf function.
3. Connext fast path simulates xReceive with _originSender = address(0); onlySource passes since trustedRemoteConnext[origin] == address(0).
4. Invoke e.g. `receiveSetXChainAllocation` with a manipulated exchange rate, or `receiveAllocations` to redirect allocations.
**How found:** Code-read the onlySource modifier, noticed no zero-address check on trustedRemoteConnext[_origin], then cross-referenced Connext's BridgeFacet source showing fast path passes address(0) as originSender when unauthenticated, and matched against Derby's supported-chain list vs Connext's supported domains.
**Exploitation:** Attacker sends a cross-chain message from an unsupported Connext domain; the fast-path delivery sets originSender to address(0), matching the unset trustedRemoteConnext entry, so xReceive dispatches to any onlySelf function. Attacker then sets a favorable exchange rate to drain a vault via LP redemption, corrupts allocations, or blocks rebalancing.
**Escalation:** Single spoofed message unlocks all onlySelf functions: allocation corruption, exchange-rate manipulation to drain vaults, totalUnderlying corruption to block rebalancing, and vault shutdown.
**Insight:** When a trust check compares a caller-supplied value against a mapping default, an unset key equals the zero address — enumerate the bridge's supported domains and find any not configured in the allowlist to get a free zero-sender match.
