# Unauthorized coins transfer from locking account(s)

Cosmos SDK lockup accounts trust msg.Sender from MsgExecute instead of ctx, letting anyone drain unlocked funds from a victim's periodic-locking-account.

- Payout: hidden
- Severity: critical
- Program: Cosmos
- Found by: unknown_feature
- Disclosed: 2025-06-29
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/2976481
- Library page: https://bugbountylibrary.com/r/h1%3A2976481
- Tags: area:web3 domain:web3 impact:funds-loss kind:bounty platform:hackerone sev:critical tech:solidity technique:chained technique:source-review vuln:access-control vuln:auth-bypass

**Target:** x/accounts lockup module (periodic-locking-account)
**Root cause:** Lockup SendCoins validates msg.Sender against the account owner, but msg.Sender is attacker-controlled inside MsgExecute and never checked against the authenticated context sender.
**Steps:**
1. Build cosmos-sdk and start a chain via setup_chain script
2. Create a periodic-locking-account owned by victim with a short locking period
3. Wait for locking period to end so funds are unlocked
4. Submit MsgExecute to the lockup account with a SendCoins message whose msg.Sender is set to the victim owner and recipient set to attacker
5. Observe funds transferred to attacker
**How found:** Code reading of lockup.go SendCoins/checkSender revealed sender taken from message rather than ctx; compared with multisig account which correctly reads sender from ctx, exposing the inconsistency.
**Exploitation:** Attacker crafts MsgExecute targeting the victim's lockup account, embedding a SendCoins message with msg.Sender spoofed to the owner; checkSender compares against the spoofed value and passes, moving unlocked funds to the attacker.
**Insight:** When a module validates an identity field from a user-supplied message, compare sibling modules (e.g. multisig) that pull the same identity from ctx — the divergence marks the vulnerable path.
