- Make sure that an account has the expected address (pubkey).
- For example, verifying that an
admin
account is associated with the config account using the constrainthas_one = admin
.
- Verify that an account is owned by the expected program by using Anchor's
Account<
info, T>type that checks the owner (instead of
AccountInfo<info>
).
- This vulnerability occurs when an account is not signed so anyone who knows the user pubkey can use it in a transaction.
- A solution is to replace
AccountInfo<'info>
withSigner<'info>
.
- Verify that the target program to be invoked has the correct address.
- For example, if the main program invokes an external program to transfer funds from a user account to a pool account and the program does not verify the address of the external program, an arbitrary code execution can happen.
- To mitigate, replace the
AccountInfo<'info>
type (which is unverified) with Anchor'sProgram<'info, T>
type. - Note that Anchor supports
System
,Token
, andAssociatedToken
programs, but other programs must have the CPI modules generated. - To learn more, check out soldev.app's lesson on Arbitrary CPI.
- Beware of arithmetics and precision issues.
- Validate account data and instruction parameters.
- Make sure instructions are executed in the correct order.
- Make sure to prevent unintended behavior when passing duplicated accounts.
- Make sure not to re-initialize an already-initialized account.
- Make sure to refrain from re-using an already closed account.
- To learn more, check out soldev.app's lesson on Reinitialization Attacks.
- Use canonical bump to avoid multiple valid PDAs (never let the user define an arbitrary bump).
- Do not share global PDA authorities; instead, use account-specific PDAs.
- To learn more, check out soldev.app's lesson on Bump Seed Canonicalization.