La validación faltante de signatario y propietario causa más exploits de programas de Solana que cualquier otra clase de error. Cada instrucción debe probar que las cuentas correctas firmaron y pertenecen a los programas esperados.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
#[derive(Accounts)]pub struct TransferOut<'info> { #[account(mut, has_one = authority)] pub vault: Account<'info, Vault>, pub authority: Signer<'info>,}// Comprobación manual de signatario en una autoridad UncheckedAccountrequire!(ctx.accounts.authority.is_signer, ErrorCode::MissingSigner);// Comprobación manual de propietario en una mint UncheckedAccount (una mint no firma)require_keys_eq!(*ctx.accounts.mint.owner, anchor_spl::token::ID, ErrorCode::InvalidOwner);
Cuándo usar esto:
Cualquier instrucción que mueva lamports o tokens.
Cambios de autoridad y actualizaciones de configuración.
Aceptar AccountInfo de metadatos proporcionados por el usuario.
Revisar hallazgos de auditoría sobre control de acceso.
Signatario en la cuenta incorrecta - El pagador de tarifas firma pero la autoridad no. Solución:has_one o constraint = authority.key() == vault.authority explícito.
PDA como autoridad sin invoke_signed - CPI falla o usa un signatario incorrecto. Solución: Pasar semillas a CpiContext::new_with_signer.
Propietario de la cuenta de token - Account<'info, TokenAccount> ya comprueba que la cuenta es propiedad del programa SPL Token, y .owner en ese tipo es el campo de autoridad de token, no el propietario del programa. Solución: Añadir una comprobación sobre la autoridad del token: constraint = vault_token.owner == vault.key().
Sysvar como UncheckedAccount - El atacante pasa una sysvar falsa. Solución: Usar cuentas tipadas Sysvar<'info, Clock>.
Multifirma - La multifirma SPL requiere metadatos de signatario adicionales. Solución: Coincidir con el diseño de multifirma del programa de tokens.
Restauración de cuenta cerrada - Una cuenta cerrada puede ser reasignada en la misma transacción en algunos patrones. Solución: Ver las protecciones de reinicialización.
Solo si tu instrucción lo permite explícitamente; nunca asumas que el pagador es igual a la autoridad.
¿Puede un PDA ser un Signer en la macro de cuenta?
No para transacciones de usuario; los PDA firman solo a través de invoke_signed dentro del programa.
¿Qué comprueba has_one?
Igualdad entre un campo de la cuenta (por ejemplo, vault.authority) y la clave de otra cuenta.
¿Es AccountInfo alguna vez seguro sin comprobaciones?
Raramente; solo para leer de forma inmutable IDs de programa verificados que luego usas require_keys_eq!.
¿Cómo audito la cobertura de signatarios?
Mapea cada mutación de estado a los signatarios requeridos; busca UncheckedAccount sin restricciones.
¿Las comprobaciones de propietario detienen la lectura de datos?
Cualquier programa puede leer cualquier cuenta; las comprobaciones de propietario evitan escrituras no autorizadas y la confianza en la deserialización de tipos.
¿Qué pasa con los delegados de token?
El delegado puede mover tokens hasta delegated_amount; valida el delegado como signatario en transferencias delegadas.
¿Cómo difiere Anchor 0.32.1?
La sintaxis de restricciones es estable; siempre fija anchor-lang 0.32.1 para que coincida con el manifiesto para auditorías reproducibles.
¿Puedo omitir el signatario para ix de solo vista?
Sí, si la instrucción es verdaderamente de solo lectura y no puede perjudicar a otros; aún valida la propiedad de la cuenta para el análisis.
¿Cómo pruebo la falta de signatario?
Pruebas LiteSVM 0.6.x con is_signer: false en los metadatos de la autoridad; espera MissingRequiredSignature.