GHSA-x442-m7cc-hr92 kora-lib: Unrecognized Instruction Types Create Empty Stubs That Bypass Fee Payer Policy
SummaryWhen inner CPI instructions use instruction types not recognized by Kora's parser (including Token-2022 extension instructions like `ConfidentialTransfer`, `TransferFeeExtension::WithdrawWithheldTokens`, etc.), they are reconstructed as stub instructions with empty accounts and empty data. These stubs fail deserialization during fee payer policy validation and are silently skipped, meaning any fee payer usage within those instructions goes completely unchecked.Severity**Medium**Affected Component**File:** `crates/lib/src/transaction/instruction_util.rs`**Functions:** `reconstruct_system_instruction()`, `reconstruct_spl_token_instruction()`**Lines:** 750–753, 1187–1189Root CauseThe instruction reconstruction functions have a catch-all `_ =>` arm for unrecognized instruction types that creates a stub `CompiledInstruction` with the correct `program_id_index` but **empty `accounts` and empty `data`**. When this stub reaches the fee payer policy parsing (`parse_system_instructions` / `parse_token_instructions`), deserialization of empty data fails. The parsing functions also have a catch-all `_ => {}` that silently skips the failed instruction. The result: the instruction exists in `all_instructions` (so program allowlist checks pass), but fee payer policy is never enforced on it.Vulnerable CodeStub CreationThe stub builder:Silent Skip During Policy ParsingProof of ConceptAffected Token-2022 Extension InstructionsThe following Token-2022 extension instruction types are NOT handled by Kora's parser and would produce empty stubs:| Extension | Instruction | Risk if Fee Payer is Authority |
|-----------|------------|-------------------------------|
| `TransferFeeExtension` | `WithdrawWithheldTokensFromMint` | Fee payer as withdraw authority can drain withheld fees |
| `TransferFeeExtension` | `WithdrawWithheldTokensFromAccounts` | Same |
| `TransferFeeExtension` | `HarvestWithheldTokensToMint` | Fee collection manipulation |
| `ConfidentialTransfer` | `Transfer` | Hidden transfer amounts bypass fee tracking |
| `ConfidentialTransfer` | `Withdraw` | Hidden withdrawals |
| `InterestBearingMint` | `UpdateRate` | Fee payer as rate authority can manipulate interest |
| `TransferHook` | `Execute` | Arbitrary hook execution |
| `GroupMemberPointer` | `Update` | Metadata manipulation |
| `MetadataPointer` | `Update` | Metadata manipulation |
| `PermanentDelegate` | `Transfer` (via delegate) | Delegate-based unauthorized transfers |Code Path TraceVerifiable TestImpact**Fee Payer Policy Bypass:** Token-2022 extension instructions that use the fee payer as an authority are invisible to policy enforcement.**Forward-Looking Risk:** As Solana and SPL Token-2022 add new instruction types, they will automatically bypass all fee payer policy checks in Kora.**Precondition:** Requires the fee payer to hold some authority role (e.g., `withdraw_withheld_authority`, `permanent_delegate`) for Token-2022 accounts. This is unlikely in typical deployments but possible in misconfigured setups.RecommendationReject transactions containing inner instructions with unrecognized types (fail-secure):Alternatively, maintain a list of known-safe instruction types that don't involve authority checks, and only reject truly unknown types.References`crates/lib/src/transaction/instruction_util.rs:750-753` — system instruction catch-all`crates/lib/src/transaction/instruction_util.rs:1187-1189` — SPL token instruction catch-all`crates/lib/src/transaction/instruction_util.rs:316-319` — `build_default_compiled_instruction`[SPL Token-2022 instruction types](https://github.com/solana-labs/solana-program-library/tree/master/token/program-2022/src/extension) — full list of extension instructions
CVSS v4.0 score: 6.9