8 ejemplos para empezar con la seguridad de programas: 5 básicos y 3 intermedios. Cubre el modelo de amenazas de Solana, la validación de cuentas, las comprobaciones de firmantes y el diseño de cierre por fallo en Anchor 0.32.1.
Solo el programa propietario debe interpretar los datos de la cuenta.
// Account<'info, T> ya aplica owner == crate::ID - no se necesita restricción.pub vault: Account<'info, Vault>,/// CHECK: propietario validado manualmentepub raw_vault: UncheckedAccount<'info>,// en el manejador, para la cuenta no verificada:require_keys_eq!(*ctx.accounts.raw_vault.owner, crate::ID, ErrorCode::InvalidOwner);
Anchor Account<'info, T> comprueba automáticamente owner == crate::ID para tus tipos.
No escribas constraint = vault.owner == ... en un Account<'info, T> - Deref a tu struct de estado, por lo que .owner significa un campo en tus datos, no el propietario del programa de la cuenta.
AccountInfo y UncheckedAccount omiten la comprobación del propietario; usa *account.owner en AccountInfo y valida manualmente.
Los ataques de confusión de tipos pasan tipos de cuenta incorrectos sin comprobaciones de propietario.
Las cantidades de tokens y las participaciones pueden desbordarse en las compilaciones de lanzamiento a menos que el espacio de trabajo active las comprobaciones de desbordamiento.
let new_balance = old_balance .checked_add(amount) .ok_or(ErrorCode::Overflow)?;
A menos que overflow-checks = true esté configurado en [profile.release] (la plantilla predeterminada de Anchor lo configura), los +/-/* simples se envuelven silenciosamente; verifica que la bandera esté presente en el repositorio auditado.
Aún prefiere checked_*, saturating_* o intermediarios u128: un desbordamiento que causa pánico aborta la instrucción con un error genérico en lugar de uno tipificado.
El redondeo favorece al protocolo, no al usuario, en la división.
Drena los lamports al destino y pon a cero los datos para evitar su reactivación.
#[account( mut, close = destination,)]pub temp: Account<'info, Temp>,#[account(mut)]pub destination: SystemAccount<'info>,
El atributo close de Anchor drena los lamports al destino, pone a cero la longitud de los datos y reasigna la cuenta al Programa del Sistema para que no pueda ser revivida dentro de la transacción.
El destination debe ser escribible; márcalo como #[account(mut)] o close = destination fallará.
Asegúrate de que no haya referencias abiertas ni cierres duplicados en la misma transacción.
Cerrar a una cuenta controlada por el atacante filtra el alquiler si falta la comprobación de autoridad.
Versiones de la pila: Esta página se escribió para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 y LiteSVM 0.6.x.
Revisado por Chris St. John·Última actualización: 16 jul 2026