Soteria — A Vulnerability Scanner for Solana Smart Contracts

October 8, 2021

Solana is a fast-growing blockchain with a unique type of smart contracts — called Solana programs. This article introduces Soteria, a security tool that automatically scans Solana programs to detect common security pitfalls.

Common pitfalls in Solana smart contracts

Neodyme recently collected a list of common pitfalls in Solana smart contracts, falling into five categories:

  • Missing ownership check
  • Missing signer check
  • Solana account confusions
  • Arbitrary signed program invocation
  • Integer overflow & underflow

As an example, the code below illustrates a common pitfall of missing signer check.

fn update_admin(
  accounts: &[AccountInfo], 
  admin: [u8; 32]
) -> ProgramResult {
  let acc_iter = &mut accounts.iter();
  let admin_info = next_account_info(acc_iter)?;
  let staking_info = next_account_info(acc_iter)?;        
  // if !admin_info.is_signer {        
  //     return Err(ProgramError::MissingRequiredSignature);        
  // }        
  let mut staking = StakingInfo::try_from_slice(&staking_info.data.borrow())?;
  if staking.admin == [0; 32] {
    staking.admin = admin;        
  } else if staking.admin == admin_info.key.to_bytes() {
    staking.admin = admin;        
  } else {
    return Err(StakeError::AdminRequired.into());
  }
  let _ = staking.serialize(&mut &mut staking_info.data.borrow_mut()[..]);        
  Ok(())
}

The function update_admin updates the admin of a staking_info account. It attempts to ensure that the function is only callable by the current admin of staking_info by comparing staking.admin to admin_info account’s public key. It must check that admin_info has actually signed this operation. This can be done by adding the check if !admin_info.is_signer. Otherwise if the check is missed, an attacker can update the admin to any account.

The reason is that, in Solana, users can supply arbitrary accounts when invoking a smart contract, so there’s nothing stopping a malicious user from just supplying a fakeadmin_info with admin_info.key.to_bytes()as staking.admin and their own account as the new admin.

Soteria — Accurately detecting common pitfalls

Powered by the GreenCore technology, Soteria can automatically detect security vulnerabilities in Solana programs by checking all code paths against these common pitfalls. The basic idea is to look at the data flow of each user account supplied to the program and flag it as untrustful if its validity is not properly checked in the program’s execution context. Figure 1 shows a screenshot of the missing signer check detected by Soteria in the update_admin code. Figure 2 shows a screenshot of an arithmetic overflow/underflow detected by Soteria in the Jet protocol.

Figure 1. A screenshot of missing-signer-checker vulnerabilities found by Soteria
Figure 2. A real vulnerability found by Soteria in the Jet protocol and and fixed by their developers

How to use Soteria

Under Solana program’s directory (where Xargo.tomlexists), invoke soteria . or soteria -analyzeAll .

# Option 1: 
soteria .
# Option 2: 
#   "-analyzeAll" the tool will detect vulnerabilities in all library code paths
soteria -analyzeAll .
# run "cargo build-bpf" if you see "toolchain 'bpf' is not installed"

The dot . is a shortcut for the following cargo build command:

cargo +bpf build --target bpfel-unknown-unknown --release

Depending on the code complexity, Soteria currently adds only a second or so to the build time. At the end of the screen, it also shows a summary of the findings and generates a report that can be inspected in the browser.

How to install Soteria

Option 1 (Linux terminal)

sh -c "$(curl -k https://supercompiler.xyz/install)"
# Depending on your system, you may need to change your PATH environment variable to include soteria
export PATH=$PWD/soteria-linux-develop/bin/:$PATH

Option 2 (Docker)

docker run -v $PWD/jet-v1/:/workspace -it greencorelab/soteria:0.1.0 /bin/bash

Jump start

soteria --version

Questions?

Please email contact@soteria.dev

For all blogs by Soteria, Please visit https://www.soteria.dev/blogs