SPL Token Mint Authority Remediation
How to fix mint authority vulnerabilities in Solana token programs.
SPL Token Mint Authority Remediation
Overview
Related Detector: SPL Token Mint Authority
Missing mint authority validation allows unauthorized token minting, causing inflation and devaluing existing holdings. The fix requires validating the mint account, verifying the authority signer matches the mint’s authority field, and enforcing supply caps.
Recommended Fix
Before (Vulnerable)
// No mint validation, no authority check, no supply cap
let ix = spl_token::instruction::mint_to(
&spl_token::id(), mint.key, destination.key, authority.key, &[], amount,
)?;
invoke(&ix, accounts)?;
After (Fixed)
// Validate mint account
if mint.owner != &spl_token::id() { return Err(ProgramError::IncorrectProgramId); }
if mint.key != &EXPECTED_MINT { return Err(ProgramError::InvalidAccountData); }
// Validate authority
if !authority.is_signer { return Err(ProgramError::MissingRequiredSignature); }
let mint_data = Mint::unpack(&mint.data.borrow())?;
if mint_data.mint_authority != COption::Some(*authority.key) {
return Err(ProgramError::InvalidAccountData);
}
// Enforce supply cap
require!(mint_data.supply + amount <= MAX_SUPPLY, SupplyCapExceeded);
let ix = spl_token::instruction::mint_to(
&spl_token::id(), mint.key, destination.key, authority.key, &[], amount,
)?;
invoke(&ix, accounts)?;
Alternative Mitigations
1. Anchor mint constraints
#[derive(Accounts)]
pub struct MintTokens<'info> {
#[account(mut, mint::authority = authority)]
pub mint: Account<'info, Mint>,
pub authority: Signer<'info>,
}
2. Disable mint authority
After initial distribution, set mint authority to None to prevent future minting:
let ix = spl_token::instruction::set_authority(
&spl_token::id(), mint.key, None, AuthorityType::MintTokens,
authority.key, &[],
)?;
3. Governance-controlled minting
Route all minting through a governance program that requires proposal approval.
Common Mistakes
Mistake 1: Checking signer but not matching against mint authority
// INCOMPLETE: any signer can mint
if !authority.is_signer { return Err(...); }
// Missing: mint_data.mint_authority == Some(*authority.key)
Mistake 2: No supply cap
// RISKY: allows unlimited minting even with valid authority
Mistake 3: Not validating the mint account itself
// WRONG: attacker passes a mint they control
// Must verify: mint.key == EXPECTED_MINT