Skip to main content
Sigvex

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.

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

References