Seguridad del Contrato inteligente: Comprender y Prevenir Vulnerabilidades de Reentrada

Los ataques de reentrada representan una de las amenazas de seguridad más significativas en el desarrollo de contratos inteligentes. Este análisis técnico explica la mecánica detrás de las vulnerabilidades de reentrada y proporciona estrategias de defensa completas para proteger sus contratos.

¿Qué es un ataque de reentrancia?

La reentrancia ocurre cuando una función en un contrato inteligente puede ser interrumpida durante su ejecución y llamada nuevamente antes de que la primera invocación esté completa. En términos técnicos, la reentrancia explota el contexto de ejecución de un contrato inteligente al manipular el flujo de control a través de llamadas externas.

Cuando el Contrato A interactúa con el Contrato B, la vulnerabilidad surge porque el Contrato B puede llamar de vuelta al Contrato A mientras la ejecución del Contrato A aún está en progreso. Este patrón de llamada recursiva puede ser utilizado para manipular el estado del contrato y drenar fondos.

Mecánicas de Ataque: Cómo Funciona la Reentrancia

Considera un escenario con dos contratos:

  • Contrato A: Un contrato vulnerable que posee 10 ETH
  • Contrato B: Un contrato malicioso con 1 ETH depositado en el Contrato A

El flujo de ataque sigue este patrón:

  1. El contrato B llama a la función withdraw() en el contrato A
  2. El contrato A verifica que el saldo del contrato B es mayor que 0 (pasa la verificación)
  3. El Contrato A envía 1 ETH al Contrato B antes de actualizar su registro de saldo
  4. La transferencia de ETH activa la función de respaldo del Contrato B
  5. Dentro de la función de respaldo, el Contrato B llama nuevamente a la función de retiro del Contrato A ()
  6. Dado que el Contrato A aún no ha actualizado el saldo del Contrato B, la verificación pasa nuevamente.
  7. El contrato A envía otro ETH al contrato B
  8. Este ciclo se repite hasta que el Contrato A se queda sin fondos

La vulnerabilidad crítica radica en el orden de ejecución del Contrato A: realiza la llamada externa ( enviando ETH) antes de actualizar su estado interno ( estableciendo el saldo en cero).

Tres técnicas de defensa contra la reentrada

1. Protección a Nivel de Función con el Modificador noReentrant

El modificador noReentrant implementa un mecanismo de bloqueo que impide que una función sea llamada recursivamente:

solidez // Variable de estado para rastrear la reentrancia bool privado bloqueado = falso;

// Modificador para prevenir la reentrada modificador noReentrant() { require(!locked, "Llamada reentrante"); bloqueado = verdadero; _; bloqueado = falso; }

// Función protegida función retirar() pública noReentrante { // Lógica de la función aquí }

Este enfoque bloquea los intentos de reentrada al mantener una variable de estado amplia del contrato que previene la ejecución concurrente de funciones protegidas.

2. Patrón de Interacción de Comprobación-Efecto

Este patrón reestructura el código para seguir una secuencia específica de operaciones:

  1. Comprobar: Verificar condiciones (e.g., saldo > 0)
  2. Efecto: Actualizar variables de estado ( p. ej., establecer saldo = 0)
  3. Interacción: Realizar llamadas externas (e.g., transferir ETH)

Comparando código vulnerable vs. código protegido:

Vulnerable: solidez función retirar() externo { uint bal = balances[msg.sender]; require(bal > 0);

// Interacción antes del Efecto (vulnerable)
(bool enviado, ) = msg.sender.call{value: bal}("");
require(sent, "Error al enviar Ether");

balances[msg.sender] = 0; // Puede que nunca se alcance si ocurre reentrada

}

Protegido: solidity function withdraw() externo { uint bal = balances[msg.sender]; require(bal > 0);

// Efecto antes de la Interacción (secure)
balances[msg.sender] = 0;

(bool enviado, ) = msg.sender.call{value: bal}("");
require(sent, "Error al enviar Ether");

}

Al actualizar el estado antes de las interacciones externas, el contrato permanece seguro incluso si la llamada externa activa una llamada a una función reentrante.

3. Protección Cruzada de Contratos con GlobalReentrancyGuard

Para proyectos con múltiples contratos interactuantes, un guardia de reentrancia compartido proporciona una protección integral:

solidez // Contrato central para protección contra reentradas contrato GlobalReentrancyGuard { mapeo(dirección => bool) privado _estado;

función _beforeNonReentrant() interna {
    require(_status[msg.sender] == false, "ReentrancyGuard: llamada reentrante");
    _status[msg.sender] = true;
}

función _afterNonReentrant() interna {
    _status[msg.sender] = false;
}

}

// Usando el guardia en un contrato contract ProtectedContract es GlobalReentrancyGuard { función protectedFunction() externa { _beforeNonReentrant();

    // Lógica de función protegida aquí
    
    _afterNonReentrant();
}

}

Esta técnica previene la reentrancia entre contratos manteniendo un registro de estado global que rastrea el estado de ejecución a través de múltiples contratos en su ecosistema.

Mejores Prácticas de Seguridad

Para garantizar una protección integral contra ataques de reentrada:

  1. Aplica múltiples capas de defensa: Combina el patrón de chequeo-efecto-interacción con protecciones contra reentradas para máxima seguridad
  2. Realiza pruebas exhaustivas: Utiliza herramientas especializadas como Mythril para detectar posibles vulnerabilidades de reentrancia.
  3. Sigue patrones establecidos: Implementa medidas de seguridad de manera consistente en todos los contratos de tu proyecto
  4. Utilice dependencias auditadas: Incorpore bibliotecas probadas en batalla con registros de seguridad comprobados.
  5. Actualiza los saldos primero: Siempre modifica el estado antes de realizar llamadas externas o transferencias.

Al implementar estos mecanismos de defensa, puedes proteger eficazmente tus contratos inteligentes contra uno de los vectores de ataque más peligrosos en la seguridad blockchain.

ETH3.52%
Ver originales
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
  • Recompensa
  • Comentar
  • Republicar
  • Compartir
Comentar
0/400
Sin comentarios
  • Anclado
Opera con criptomonedas en cualquier momento y lugar
qrCode
Escanee para descargar la aplicación Gate
Comunidad
Español
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)