Solana is a rapidly growing smart contract platform, consistently ranking in the top three alongside Ethereum and Polkadot.  For developers writing Solana smart contracts and attackers looking to exploit them, the security of these smart contracts is a major concern.

Since smart contracts are essentially pieces of software executed on chain, in Solana they are called “programs”.

Solana Smart Contracts: Top 5 Vulnerabilities and Pitfalls

All smart contract platforms have their quirks that lead to insecure smart contracts, and Solana is no exception.  Some of the most common vulnerabilities within Solana smart contracts that an attacker can exploit or hack include the following:

1. Missing Ownership Check

Smart contracts commonly contain privileged functionality that should only be accessible to certain accounts.  If this is the case, then a smart contract should verify that an account is trusted before running this privileged functionality.

All Solana accounts are owned by smart contracts–to this rule there is no exception. Only contracts are allowed to modify accounts’ data. It is the smart contract developers’ task to implement necessary authorization controls, including the verification of the transaction sender’s digital signature.

Account metadata struct in Solana includes the owner field that indicates the public key associated with that account’s owner.  To validate that an account is trusted, the public key stored in its owner field should be checked against expected values.

Some Solana smart contracts use config or other utility accounts to store trusted data or the public key of an administrator’s account.  Those accounts have to be provided by users running the smart contract and executing certain actions.

However, if a contract does not validate the owner of a utility account, it could be vulnerable to exploitation.  An attacker could bypass access controls with a fake config account if the account’s owner isn’t verified to be as expected and trick the smart contract to perform privileged operations.  

Instead of inherently trusting certain accounts, Solana smart contracts should verify that they are owned by the contract’s owner.

2. Lack of Signature Validation

For restricted functionality, checking that the public key of the calling account matches that of an authorized user is an important first step.  However, an account can technically set its data to whatever it wants; it’s just data.

Verification occurs when the account signs an operation with the private key associated with that public key.  If a smart contract fails to check that an operation is signed, then anyone can call that instruction as long as their account contains the correct public key.  

Solana smart contracts should validate that an operation is signed with an appropriate private key before executing privileged functionality.

3. Integer Overflows and Underflows

Rust (and other programming languages) store values in fixed-size variables.  This means that these variables can only hold a certain range of values.  If an operation results in a value outside of this range, it creates an integer overflow or underflow.

In the debug mode, Rust will check for overflows and underflows, but this is not true in the release mode (which is used by the Solana BPF toolchain).  If a value moves outside the range of values that a variable can support, it will wrap around.

An attacker can exploit this fact to evade validation of transfers of value.  If a program checks that a + b < c and a and b are not added together in the transfer, then an attacker could choose the values of a and b to overflow the check.  Later, when the transfer occurs, only one value is used, which means that it will not overflow and a large amount of value will be sent to the indicated address.

Integer overflows and underflows typically result from unsafe math and unsafe casts between variable types.  If it uses checked versions of the arithmetic and cast operations, a smart contract will throw an error if an overflow/underflow occurs, causing the transaction to be canceled.

4. Failure to Validate External Programs

Smart contracts are designed to interact with one another and call functions from external programs.  Solana’s design patterns state that programs to be invoked within a function should be passed to that function as an argument.

Function arguments may be under the user’s control, which means that an attacker could supply malicious inputs.  By passing a lookalike program as an argument to a vulnerable function, an attacker could convince the smart contract to run that program (and sometimes even assume the calling program’s identity) instead of the one that they intended.

Like verifying accounts based on their public keys, smart contracts should verify the programs that they invoke based on their public keys.  This verifies that the program is the one that the smart contract intended to invoke.

5. Missing Account Structure Validation

A Solana smart contract may define multiple different accounts for different purposes.  These attacks can have different structures and contain different types of data.

Account data is passed to a Solana smart contract function as a byte array, which the recipient then deserializes based on the structure of the expected account type.  This creates an opportunity for exploitation where a malicious user creates an account of one type and passes it to a smart contract function as an instance of another type of account.

A check of the ownership of the account would pass ownership checks if it was created by one of the contract’s own functions.  However, the data associated with that account would be interpreted based on the perceived account type, which could allow the attacker to set certain values and pass checks.

This attack takes advantage of the fact that one type of account could be substituted for another.  If an account’s data starts with an identifier unique to that type of account and that value is checked by the functions using that account, then this attack is not possible.

Securing Solana Smart Contracts

The Solana smart contract platform has some security advantages, such as its use of Rust for smart contract development.  However, even Solana smart contracts can be hacked.  Before deploying a smart contract to the blockchain, smart contracts should undergo a security audit to find and fix as many vulnerabilities as possible before they can be exploited by an attacker.  To learn more about our Solana smart contract security audits, reach out to our blockchain security experts at halborn@protonmail.com.

Rob Behnke
04.11.2022