Saltar al contenido

Protección contra la repetición de mensajes entre cadenas

La protección contra replay vincula un mensaje de origen autenticado a una versión del protocolo y a un dominio de destino, y permite reintentos sin generar más de un efecto económico correcto.

Actualizado

Solo con fines educativos; no constituye asesoramiento de inversión. Invertir puede ocasionar pérdidas.

Respuesta directa

La protección contra la repetición de mensajes entre cadenas garantiza que un mensaje de origen autenticado no produzca más de un efecto económico correcto en el dominio de destino previsto. Un relayer puede entregar la misma prueba varias veces y un intento fallido puede admitir reintento, pero un mensaje ya completado no debe volver a emitir, desbloquear ni invocar al receptor.

Autenticidad, finalidad y protección contra replay son comprobaciones distintas. Una firma, atestación de validadores o prueba de almacenamiento válida puede autenticar datos sin demostrar que el evento de origen sea final, que destino y receptor esten vinculados o que el destino no lo haya procesado ya. Del mismo modo, un relayer autorizado es solo una via de entrega; su identidad no sustituye la autenticación del mensaje.

No existe un messageId universal. La especificación concreta determina la serialización y la identidad. Un sobre robusto suele vincular protocolo y versión, dominio y messenger o emisor de origen, remitente original, nonce o identidad de transacción/log de origen, dominio y receptor de destino, valor, payload y vencimiento. Wormhole, CCTP, Optimism y ERC-5164 usan campos y maquinas de estado distintos; sus identificadores no son intercambiables.

Como funciona

Una acción de origen emite o almacena un mensaje. Tras la política exigida de confirmación o finalidad, validadores, guardianes o un sistema de pruebas lo autentican. En destino, el verificador comprueba la raiz o conjunto de firmas pertinente, versión, remoto de confianza, destino, receptor, payload y limites temporales. El receptor deriva la identidad definida por el protocolo y consulta el estado processed persistente antes de producir un efecto externo.

La entrega suele ser al menos una vez, mientras que el efecto comercial buscado ocurre efectivamente una vez. Una máquina de estados util distingue nunca intentado, en proceso, fallido o reintentable, y correcto o consumido. Una llamada de destino fallida no es automaticamente un ataque de replay. ERC-5164, por ejemplo, exige que un mensaje se ejecute correctamente como maximo una vez y permite otro intento tras un fallo. Siguen rigiendo las reglas propias del producto sobre reintentos, gas y valor.

El indicador de replay o guard de procesamiento debe fijarse antes de una llamada externa no fiable, controlando la reentrada. Si revierte toda la transacción, normalmente revierte también ese cambio y queda una ruta definida de reintento; si el protocolo captura intencionadamente un fallo downstream, debe registrar un estado fallido distinto sin retener por error valor ni efectos parciales. El receptor también debe ser idempotente cuando sistemas downstream sean accesibles por otra via.

El alcance del nonce importa. Un nonce secuencial impone orden, pero un mensaje ausente puede bloquear los siguientes. Un nonce no ordenado o bitmap permite entregas independientes, pero exige calcular exactamente word y bit. En lotes debe definirse si todo el lote es atómico o si cada hoja tiene prueba y estado processed propios. Marcar solo la raiz del lote tras una ejecución parcial puede duplicar hojas correctas o dejar varadas las fallidas.

La política de reorganización del origen forma parte de la seguridad. Una observación firmada antes de suficiente finalidad puede seguir siendo criptográficamente válida aunque el evento deje de ser canonico. Las actualizaciones son otro limite: layout de almacenamiento del proxy, mappings processed, dominios de versión, entry points antiguos, rotación de peers y fork o reutilizacion de chain ID deben conservar o invalidar deliberadamente identidades anteriores sin reabrir mensajes consumidos.

Use este flujo:

  1. Fije protocolo, versión desplegada, dominios, messenger o emisor de confianza, remitente, receptor, valor, payload, nonce o identidad del evento y semántica de vencimiento.
  2. Reproduzca la codificación canonica y el vector de prueba de messageId; rechace concatenaciones ambiguas, campos omitidos y supuestos tomados de otro puente.
  3. Verifique inclusión y política de finalidad o confirmaciones; después, raiz, quorum de firmas, conjunto de validadores o guardianes y versión correctos.
  4. Verifique por separado destino, receptor, remitente cross-domain, valor, payload y vencimiento; trate al relayer como transporte, no como autoridad.
  5. Lea el estado persistente y entre en estado processing o consumed antes de toda llamada externa no fiable, probando explicitamente reentrada y comportamiento de revert.
  6. Defina transiciones correctas, fallidas y reintentables, nonce ordenado o bitmap, atomicidad del lote y contabilidad de valor; demuestre que una entrega repetida no repite una hoja correcta.
  7. Pruebe actualizaciones, migración de storage, entry points legacy deshabilitados, rotación de peers, forks y recuperación; concilie receipts, eventos, estado processed y saldos de destino.

Ejemplos

  • Vinculacion del dominio de destino. Dos instrucciones tienen nonce 42 y valor 1,000, pero una apunta a la cadena 10 y otra a la cadena 8453. Un identificador que omite el destino trata 2 messages como candidatos a colisión; una codificación canonica que lo vincula produce 2 distinct IDs. El hash y la representación del dominio proceden del protocolo.
  • Bitmap no ordenado. Para el nonce 513, word = floor(513 / 256) = 2, bit = 513 mod 256 = 1 y mask = 1 << 1 = 2. El primer éxito cambia la word 2 de 0 a 2. Un duplicado obtiene 2 & 2 = 2 y se rechaza; el nonce 512 usa independientemente el bit 0.
  • Reintentar no crea un segundo efecto. El mismo mensaje se entrega 3 veces. Las llamadas con 110,000 y 125,000 gas fallan y revierten; la tercera usa 140,000 gas y tiene éxito una vez. El gas total es 110,000 + 125,000 + 140,000 = 375,000; a 20 gwei, equivale a 0.0075 ETH. Hay 3 entregas y 1 efecto comercial correcto.
  • Contabilidad de lote parcial. Cuatro hojas ejecutables por separado contienen 25 + 40 + 15 + 20 = 100 unidades. Las hojas 0, 1 y 3 ejecutan 25 + 40 + 20 = 85; la hoja 2 falla y deja 15 pendientes. Consumir solo la raiz deja varadas las 15; reintentar todo sin estado por hoja puede repetir las 85. Se requiere rollback atómico o estado processed por hoja.

Riesgos

  • El identificador omite la cadena o dominio de destino.
  • El identificador omite el messenger o emisor de origen.
  • Falta la versión del protocolo o mensaje en el dominio.
  • Un namespace de nonce colisiona entre remitentes o despliegues.
  • Una codificación packed ambigua crea colisiones entre campos distintos.
  • Un fork o chain ID reutilizado vuelve valido un dominio antiguo.
  • Se acepta un evento antes de suficiente finalidad y desaparece por reorganización.
  • Se acepta una raiz, conjunto de validadores o guardianes incorrecto.
  • Un dominio de firma antiguo sigue valido tras una actualizacion.
  • La corrupcion del storage del proxy reinicia o solapa el estado processed.
  • La migración omite consumidos o mantiene activo un entry point legacy.
  • El estado se marca después de la llamada externa y permite reentrada.
  • Una llamada fallida queda marcada como correcta y no admite reintento.
  • Una llamada correcta no persiste y repite su efecto económico.
  • Un nonce ordenado ausente bloquea todos los posteriores.
  • La aritmética de word, bit o invalidacion del bitmap es incorrecta.
  • El estado de raiz del lote contradice una ejecución parcial por hojas.
  • Un reintento repite hojas ya ejecutadas correctamente.
  • Se interpretan mal las unidades del deadline, expiry o reloj destino.
  • La allowlist de relayers se confunde con autorización del mensaje.

Errores comunes

  • Un nonce es globalmente único por si solo. Su namespace depende del remitente, protocolo, despliegue y dominios de origen y destino.
  • Solo un relayer autorizado evita replay. El relayer entrega; la verificación en destino y el estado consumed persistente imponen autoridad y control.
  • Toda entrega repetida es un ataque. Una red at-least-once puede reintentar un fallo; la invariante es no más de un efecto correcto.
  • Una prueba o firma válida demuestra finalidad e intención. Puede omitir el target, vincular otra versión o atestar un estado que luego se reorganiza.
  • Una transacción del puente correcta demuestra exactly-once. Verifique receipt, storage processed, eventos del receptor y saldos reales, hoja por hoja.

Temas relacionados

Fuentes

Navegación

Buscar en la wiki...