Program Upgrade Risks
Detects security risks in upgradeable Solana programs including authority validation issues.
Program Upgrade Risks
Overview
The program upgrade risks detector identifies security issues in upgradeable Solana programs, including unprotected upgrade authority, missing authority validation before upgrade operations, authority transfer without proper checks, and single points of failure in the upgrade path.
For remediation guidance, see Program Upgrade Risks Remediation.
Why This Is an Issue
Upgradeable programs on Solana can have their code replaced by the upgrade authority at any time. If the authority is a single keypair without multi-signature or timelock protection, a compromised key allows an attacker to replace the program with malicious code, stealing all funds held by the program. Programs that do not validate the upgrade authority before upgrade operations are vulnerable to unauthorized code replacement.
How to Resolve
Before (Vulnerable)
// Vulnerable: single authority, no timelock
pub fn upgrade_program(ctx: Context<Upgrade>) -> Result<()> {
// No validation of authority
invoke(
&bpf_loader_upgradeable::upgrade(
ctx.accounts.program.key,
ctx.accounts.buffer.key,
ctx.accounts.authority.key,
ctx.accounts.spill.key,
),
&ctx.accounts.to_account_infos(),
)?;
Ok(())
}
After (Fixed)
// Fixed: validated authority with timelock
pub fn upgrade_program(ctx: Context<Upgrade>) -> Result<()> {
require!(
ctx.accounts.authority.key() == ctx.accounts.config.upgrade_authority,
ErrorCode::Unauthorized
);
let config = &ctx.accounts.config;
let clock = Clock::get()?;
require!(
clock.unix_timestamp >= config.upgrade_requested_at + TIMELOCK_DURATION,
ErrorCode::TimelockNotExpired
);
invoke(
&bpf_loader_upgradeable::upgrade(
ctx.accounts.program.key,
ctx.accounts.buffer.key,
ctx.accounts.authority.key,
ctx.accounts.spill.key,
),
&ctx.accounts.to_account_infos(),
)?;
Ok(())
}
Example JSON Finding
{
"detector": "program-upgrade-risks",
"severity": "high",
"confidence": 0.7,
"message": "Upgrade authority not validated before BPF Loader upgrade CPI",
"location": { "function": "upgrade_program", "block": 0, "statement": 1 }
}
Detection Methodology
- Upgrade CPI detection: Identifies CPI calls to the BPF Loader Upgradeable program.
- Authority validation search: Checks for signer and ownership validation on the upgrade authority account.
- Authority transfer tracking: Flags authority transfers to arbitrary addresses without multi-sig.
- Timelock detection: Looks for timestamp-based delay mechanisms on upgrade operations.
Limitations
False positives: Programs managed by multi-sig wallets at the infrastructure level (outside program code) may be flagged. False negatives: Authority validation in separate governance programs is not detected.
Related Detectors
- Anchor Upgrade Security — Anchor-specific upgrade issues
- Missing Signer Check — general signer validation