Account Executable Flag Remediation
How to fix missing executable flag validation before cross-program invocations.
Remediating Missing Executable Flag Validation
Overview
Related Detector: Account Executable Flag
When a Solana program performs a CPI using an account as a program ID without verifying that the account is executable or matches a known program address, an attacker can substitute a data account. The fix is to validate the program ID against a known constant or explicitly check the executable flag before invoking.
Recommended Fix
Before (Vulnerable)
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult};
pub fn proxy_call(accounts: &[AccountInfo]) -> ProgramResult {
let target_program = &accounts[0]; // No validation!
solana_program::program::invoke(
&build_instruction(target_program.key),
&[accounts[1].clone()],
)?;
Ok(())
}
After (Fixed)
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
const KNOWN_PROGRAM: Pubkey = /* expected program address */;
pub fn proxy_call(accounts: &[AccountInfo]) -> ProgramResult {
let target_program = &accounts[0];
// Validate program identity
if target_program.key != &KNOWN_PROGRAM {
return Err(ProgramError::IncorrectProgramId);
}
solana_program::program::invoke(
&build_instruction(target_program.key),
&[accounts[1].clone()],
)?;
Ok(())
}
Alternative Mitigations
- Use Anchor’s
Program<'info, T>type: This automatically validates both the program ID and executable flag. It is the strongest defense.
#[derive(Accounts)]
pub struct ProxyCall<'info> {
pub target: Program<'info, TokenProgram>,
}
- Explicit executable check: If you cannot use a constant program ID (e.g., the program is configurable), check the executable flag directly.
if !program_account.executable {
return Err(ProgramError::InvalidAccountData);
}
- Whitelist approach: Maintain a set of approved program IDs on-chain and validate against the whitelist.
Common Mistakes
- Validating against a variable instead of a constant: Checking
program.key == config.approved_programis only safe ifconfigitself is properly validated (owner check + key check). Otherwise the attacker can pass a fake config account. - Checking executable flag without checking program identity: The executable flag confirms the account contains code, but a malicious program is also executable. Always validate the specific program ID.
- Assuming the runtime check is sufficient: While the Solana runtime rejects CPI to non-executable accounts, relying solely on runtime validation produces confusing errors and misses the opportunity to validate program identity.
- Forgetting nested CPI targets: If your program chains multiple CPIs, each program ID must be independently validated.