## Advanced Vulnerability Patterns

> Updated for Cosmos SDK v0.53.x. Advanced infrastructure patterns (§24-27) covering storage key design, consensus validation gaps, circuit breaker authorization, and cryptographic verification. Referenced by [SKILL.md](../SKILL.md) checklist items via `§` anchors.

### 24 STORAGE KEY DESIGN FLAWS

**Description**: KV store key construction allows collisions, prefix overlaps, or unauthorized access to other users' data. Keys built via string concatenation without length-prefixed encoding create ambiguous boundaries. Numeric fields serialized as variable-length strings share byte prefixes. Prefix iterators over attacker-controllable components include unintended objects.

**Detection Patterns**:

#### Pattern 1: String Concatenation Collision
```go
// VULNERABLE: String concatenation without length-prefix encoding (Finding 16)
func VaultUserKey(vaultID uint64, user string) []byte {
    return []byte(fmt.Sprintf("%d%s", vaultID, user))
}
// vaultId=1, user="2a" → key "12a"
// vaultId=12, user="a" → key "12a"  ← COLLISION!

// Even with separators, string fields containing the separator collide:
// vaultId=1, user="a|", position="b" → "1|a||b"
// vaultId=1, user="a", position="|b" → "1|a||b"  ← COLLISION!
```

#### Pattern 2: Prefix Iterator Malleability
```go
// VULNERABLE: Pool IDs serialized as strings in KV store keys (Finding 31)
func PositionKey(poolID uint64, posID uint64) []byte {
    return []byte(fmt.Sprintf("position/%d/%d", poolID, posID))
}
// poolID=42 shares byte prefix [52 50] with poolID=421
// HasAnyAtPrefix("position/42") matches "position/421/..."
// Attacker creates positions with carefully chosen pool IDs
// that prefix-collide with victim positions

// VULNERABLE: Attacker can increment pool IDs by creating empty pools
store.Iterator(PositionPrefix(poolID), nil)  // Includes poolID * 10 + N
```

#### Pattern 3: Redelegation State Lookup Bypass
```go
// VULNERABLE: Unbonding period bypass via redelegation (Finding 14)
// If a user redelegates to a validator outside the active set
// (e.g., bonded stake rank 102), then unbonds, the 21-day
// unbonding period is skipped — the state key lookup for the
// unbonding entry doesn't account for out-of-set validators.
// Attacker who steals tokens can instantly exit staking.
```

**What to Check**:
- [ ] KV store keys use length-prefixed encoding (e.g., `collections.PairKeyCodec`, `address.LengthPrefixedAddressKey`) — NOT string concatenation
- [ ] Prefix iterators cannot be confused by attacker-controllable numeric IDs (e.g., pool IDs serialized as fixed-width or length-prefixed)
- [ ] String fields in composite keys cannot contain the separator character
- [ ] `HasAnyAtPrefix` / `Iterator` with user-influenced prefix components verified to not match unintended keys
- [ ] Redelegation to out-of-set validators followed by unbonding is tested against unbonding period enforcement

**Mitigation**:
```go
// SECURE: Use length-prefixed encoding
func VaultUserKey(vaultID uint64, user string) []byte {
    key := make([]byte, 8+1+len(user))
    binary.BigEndian.PutUint64(key[:8], vaultID)  // Fixed-width
    key[8] = byte(len(user))                       // Length prefix
    copy(key[9:], user)
    return key
}

// SECURE: Use cosmossdk.io/collections key codecs
var PositionsMap = collections.NewMap(
    sb, PositionsPrefix,
    collections.PairKeyCodec(collections.Uint64Key, collections.Uint64Key),
    codec.CollValue[Position](cdc),
)
```

**References**:
- [Zellic — Cosmos Security Primer](https://www.zellic.io/blog/exploring-cosmos-a-security-primer/) (Finding 16)
- [Fault Tolerant — Cosmos Security Handbook](https://www.faulttolerant.xyz/2024-01-16-cosmos-security-1/) (Finding 31)
- [Node A-Team — Unbonding Period Bypass](https://medium.com/node-a-team/cosmos-hub-security-vulnerability-regarding-redelegation-and-unbonding-e6a2cf03e928) (Finding 14)

---

### 25 CONSENSUS VALIDATION GAPS

**Description**: Missing or incomplete validation at the consensus protocol layer — vote extensions, block timestamp manipulation, and account type checks at creation time. These allow Byzantine validators or front-running attackers to manipulate consensus-level data that downstream modules trust implicitly.

**Detection Patterns**:

#### Pattern 1: Vote Extension Forgery
```go
// VULNERABLE: PrepareProposal validates signatures but skips
// VerifyVoteExtension rules (Finding 15, SEDA Chain)
func (h *Handler) PrepareProposal(ctx sdk.Context, req *abci.PrepareProposalRequest) (*abci.PrepareProposalResponse, error) {
    for _, vote := range req.LocalLastCommit.Votes {
        // Only checks vote signature — does NOT re-run VerifyVoteExtension!
        if !verifySignature(vote) { continue }
        // CometBFT accepts late precommits without full verification
        // Byzantine validator smuggles malicious vote extension into proposal
        extensions = append(extensions, vote.VoteExtension)
    }
    // Leader unknowingly includes forged oracle data in block
}
```

#### Pattern 2: Block Timestamp Manipulation
```go
// VULNERABLE: Any module trusting ctx.BlockTime() for security-critical decisions
// CometBFT "Tachyon" (Finding 21, CSA-2026-001): inconsistency between how
// commit signatures are verified and how block time is derived breaks BFT Time
// guarantee. A faulty process CAN arbitrarily increase block time.

// These are all exploitable if block time can be manipulated:
deadline := proposal.SubmitTime.Add(votingPeriod)
if ctx.BlockTime().After(deadline) { ... }  // Governance deadlines

vestingEnd := account.EndTime
if ctx.BlockTime().After(vestingEnd) { ... }  // Vesting unlocks

price := oracle.GetTWAP(ctx, pair, window)  // Time-weighted prices
```

#### Pattern 3: Vesting on Blocked/Module Addresses
```go
// VULNERABLE: Creating vesting accounts on blocked addresses (Finding 29, ASA-2024-003)
func (ms msgServer) CreatePeriodicVestingAccount(ctx context.Context, msg *types.MsgCreatePeriodicVestingAccount) error {
    toAddr := sdk.AccAddressFromBech32(msg.ToAddress)
    // Missing: check if toAddress is a blocked address or module account
    // Funds deposited to module accounts via vesting become permanently inaccessible
    // Could also enable unintended interactions with module accounts
}
```

**What to Check**:
- [ ] `PrepareProposal` re-validates vote extensions using the same rules as `VerifyVoteExtension` — do NOT trust that CometBFT has already validated them (late precommits may skip verification)
- [ ] `ProcessProposal` independently validates all vote extensions included in the proposal
- [ ] Vote extension content is treated as untrusted input even from non-Byzantine validators
- [ ] CometBFT is patched for Tachyon (>= v0.38.21 / v0.37.18) — block timestamp manipulation
- [ ] Time-dependent logic (governance deadlines, vesting unlocks, oracle TWAPs, lockup periods, auction timers) is reviewed against block time manipulation
- [ ] `CreateVestingAccount` / `CreatePeriodicVestingAccount` reject blocked addresses and non-initialized module accounts as recipients
- [ ] SDK version includes Barberry patches (>= v0.46.13, >= v0.47.3) for vesting on blocked addresses

**References**:
- [OtterSec — SEDA Vote Extension Forgery](https://osec.io/blog/2025-06-10-cosmos-security/) (Finding 15)
- [CometBFT Tachyon CSA-2026-001](https://github.com/cometbft/cometbft/security/advisories/GHSA-c32p-wcqj-j677) (Finding 21)
- [ASA-2024-003 Vesting on Blocked Addresses](https://github.com/cosmos/cosmos-sdk/security/advisories) (Finding 29)

---

### 26 CIRCUIT BREAKER AUTHZ BYPASS

**Description**: The `x/circuit` module allows authorized accounts to disable (circuit-break) specific message types during incident response. An authorization scope bug allows an account authorized to circuit-break specific message types to reset the circuit breaker for **any** message type, even those it lacks permission for. This can re-enable message types intentionally disabled for security.

**Detection Patterns**:
```go
// VULNERABLE: Circuit breaker reset does not verify per-type authorization
// Account authorized to break MsgSend can reset MsgDelegate
func (ms msgServer) ResetCircuitBreaker(ctx context.Context, msg *types.MsgResetCircuitBreaker) error {
    // Checks: is the sender an authorized circuit breaker account? YES
    // Missing: does the sender have authority over THIS SPECIFIC message type?
    // Result: any circuit breaker account can re-enable any disabled message type
}
```

**What to Check**:
- [ ] `x/circuit` reset/authorize operations validate per-message-type permissions (not just "is this a circuit breaker account")
- [ ] Circuit breaker accounts have minimal scope — only the message types they are responsible for
- [ ] Re-enabling a circuit-broken message type requires the same or higher authorization level as disabling it
- [ ] During incident response, monitor for unexpected circuit breaker resets

**Grep Patterns** (use Grep tool):
- `circuit|CircuitBreaker|ResetCircuitBreaker` with `glob: "*.go"` in `x/`
- `x/circuit` with `glob: "*.go"` in `app/`

**References**:
- [HackerOne Report 2120609](https://hackerone.com/reports/2120609) (Finding 28)

---

### 27 MERKLE PROOF / CRYPTOGRAPHIC VERIFICATION FLAWS

**Description**: Specification-level or implementation-level flaws in cryptographic proof systems allow forging proofs that should be computationally infeasible. ICS-23 was unsound at the spec level (not just implementation). Cross-chain bridges that verify proofs differently on each side create asymmetric validation. This class has caused the largest single loss in the Cosmos ecosystem ($566M BNB bridge exploit, related flaw).

**Detection Patterns**:

#### Pattern 1: ICS-23 Absence Proof Forgery
```
// VULNERABLE: ICS-23 spec allowed proofs to carry their own spec parameters
// (Finding 3a, Dragonberry — all IBC chains, all versions)
// Validation only required input leaf prefix to CONTAIN the standard spec's
// prefix as a substring — not match exactly.
// Attacker forges absence proof to "prove" packet commitment doesn't exist
// on counterparty chain (even though it does), then triggers IBC timeout refunds
// for packets that were successfully delivered.
// Iterative drainage of ALL ICS-20 escrow accounts across ALL Cosmos networks.
```

#### Pattern 2: IAVL RangeProof Forgery
```
// VULNERABLE: Same class as Dragonberry in IAVL RangeProof system
// (Finding 30, Dragonfruit — $566M BNB bridge exploit used related flaw)
// Missing validation checks on leaf/inner-node prefix/suffix length
// allowed forging proofs against the IAVL Merkle tree.
```

#### Pattern 3: ECDSA Signature Malleability
```go
// VULNERABLE: Cosmos-side ECDSA verification accepts non-canonical s-values
// (Finding 13, Gravity Bridge)
func EthAddressFromSignature(hash []byte, sig []byte) (common.Address, error) {
    // Missing: canonical s-value validation
    // ECDSA has two valid s values per signature (elliptic curve symmetry)
    // Ethereum enforces s < secp256k1.N/2, Cosmos side does not
    // Malicious orchestrator submits non-canonical signature:
    //   Cosmos accepts → Ethereum rejects → bridge enters crash loop
    //   Selectively block validator set updates and transaction batches
}
```

**What to Check**:
- [ ] ICS-23 proof verification uses patched libraries — leaf prefix must match exactly, not just contain as substring
- [ ] IAVL library patched for Dragonfruit (prefix/suffix length validation on inner/leaf nodes)
- [ ] ECDSA signature verification enforces canonical s-value (`s < secp256k1.N/2`) on BOTH sides of any bridge
- [ ] Cross-chain proof verification is symmetric — same validation on source and destination
- [ ] Custom Merkle proof implementations do not allow proof parameters to be attacker-controlled
- [ ] If using BLS, ed25519, or other signature schemes for cross-chain verification, signature malleability is addressed

**Grep Patterns** (use Grep tool with `glob: "*.go"` in `x/`):
- `VerifyMembership|VerifyNonMembership|VerifyProof` — proof verification
- `RangeProof|InnerNode|LeafNode` — Merkle tree operations
- `EthAddressFromSignature|RecoverPubkey|Ecrecover` — signature recovery

**References**:
- [Dragonberry / ICS-23 Proof Forgery](https://forum.cosmos.network/t/ibc-security-advisory-dragonberry/7702) (Finding 3a)
- [Verichains ICS-23 analysis](https://blog.verichains.io/p/vsa-2022-103-cosmos-sdk-forging-membership)
- [Dragonfruit / IAVL RangeProof](https://forum.cosmos.network/t/cosmos-sdk-security-advisory-dragonfruit/7614) (Finding 30)
- [Gravity Bridge ECDSA malleability](https://maxwelldulin.com/BlogPost/Cryptographic-Asymmetry-and-How-To-Shut-Down-A-CosmosEthereum-Bridge) (Finding 13)
