How to prevent the Wormhole hack (2022)
February 4, 2022
What are sysvar accounts?
- used for classic operations needed within the solana runtime
What is Instructions sysvar?
- needed if an instruction needs to reference instructions in the same transaction
How the Solana wormhole hack could have been prevented (and some hypotheticals). It’s been mentioned that anchor could have helped prevent it, but I’m not actually sure.
1. Check the id!
2. Upgrade version and method (the patch)
Methods 3 - 5 would only have worked if Instructions inherited the Sysvar trait (which it doesn’t)
3. Other native library methods
4. Anchor
Bonus (for other sysvar accounts): Use get() instead of passing in accounts
1. Check the id!
The id needed to be checked, period. It doesn’t matter where.
There’s nothing wrong with using solana-program 1.7
. A check as simple as
if !check_id(instruction_sysvar_account_info.key) {
return Err(ProgramError::UnsupportedSysvar);
}
somewhere in the call hierarchy would have sufficed.
Looking through the audius project which actually still had solana-program versions of 1.7, they added checks throughout so 1.7 wasn’t a problem.
2. Upgrade Solana-program version
The patch was obviously just to upgrade solana-program, and use a checked version of the method load_instruction_at_checked
here.
Methods after this would only work is Instructions implemented Sysvar
3. Other native library methods
Using from_account_info
would also work, because id gets checked!
let instruction_sysvar_info = next_account_info(account_info_iter)?;
let instructions = Instructions::from_account_info(&instruction_sysvar_info)?;
4. Anchor
As some others have noted, using Anchor would have saved the day. But how?
Casting as a Sysvar
pub struct Example<'info> {
pub instruction_info: Sysvar<'info, Instructions>
}
This would call try_accounts
which would eventually call from_account_info
(as discussed above) from solana-program
which does check ids!
Bonus. Use get() instead of passing in accounts!
This doesn’t work for the instruction sysvar account currently (not sure why), but for other sysvar accounts the best mitigation actually is right in the official solana docs, and in the Sysvar account comments in anchor. Don’t pass in the sysvar account, and just retrieve it directly in the instruction!