Program Upgrade Risks Remediation
Overview
Related Detector: Program Upgrade Risks
Upgradeable programs can be replaced by the authority, making authority management critical. The fix is to use multi-signature governance for upgrade authority, implement timelocks on upgrades, and validate authority before every upgrade operation.
Impact. The upgrade authority can swap the program’s code at will, so weak authority management means one compromised key rewrites the logic governing all user funds in a single, irreversible transaction. Every user of an upgradeable program is implicitly trusting that authority not to — and not to be forced to — replace it maliciously.
Recommended Fix
Before (Vulnerable)
// Single keypair authority with no timelock
invoke(&bpf_loader_upgradeable::upgrade(...), accounts)?;
After (Fixed)
// Multi-sig authority with mandatory timelock
require!(ctx.accounts.authority.key() == config.multisig_authority, Unauthorized);
require!(
Clock::get()?.unix_timestamp >= config.proposal_time + TIMELOCK_DAYS * 86400,
TimelockPending
);
invoke(&bpf_loader_upgradeable::upgrade(...), accounts)?;
Alternative Mitigations
Make Program Immutable
For production programs that do not need upgrades, set the upgrade authority to None:
solana program set-upgrade-authority <PROGRAM_ID> --final
This permanently prevents code changes but requires careful testing before deployment.
Common Mistakes
Mistake: Transferring Authority Without Multi-sig
// WRONG: authority can be transferred to any address
invoke(&bpf_loader_upgradeable::set_upgrade_authority(
program_id, authority, Some(new_authority)
), accounts)?;
Authority transfers should require multi-sig approval and timelock.