El ataque de reentrada: comprensión y prevención de esta vulnerabilidad del Contrato inteligente

He pasado innumerables horas depurando exploits de contratos, y déjame decirte: los ataques de reentrada son los asesinos silenciosos de los contratos inteligentes. Son engañosamente simples pero devastadoramente efectivos. Profundicemos en qué son y cómo detenerlos antes de que drenen tus fondos.

Cuando encontré por primera vez una vulnerabilidad de reentrancia, perdí horas de sueño tratando de entender cómo alguien podría explotar un fragmento de código que parecía tan inocente. El concepto es frustrantemente simple: un contrato puede volver a llamar a otro antes de que se complete la primera ejecución.

Imagina esto: ContractA tiene 10 ETH y ContractB ha depositado 1 ETH en él. Cuando ContractB retira sus fondos, ContractA envía el ETH antes de actualizar el saldo de B a cero. Este pequeño error de secuenciación crea un gran agujero de seguridad.

¿Qué pasa? La función de fallback del contrato malicioso llama inmediatamente a withdraw() de nuevo, y dado que el saldo aún no se ha actualizado, ¡pasa la verificación de saldo nuevamente! Este ciclo se repite hasta que ContractA se agota por completo. Malditamente inteligente, ¿no?

Aquí se explica cómo un atacante explota esto en el código:

// Llamadas al contrato de ataque retiran () // ContractA envía ETH lo que activa fallback() // fallback() llama a withdraw() nuevamente antes de que se actualicen los saldos // Enjuagar y repetir hasta que se roben todos los fondos

He visto proyectos perder millones porque no entendieron este simple vector de ataque. Me enfurece cuántos desarrolladores siguen cometiendo este error de novato.

Tres técnicas para proteger tus contratos

  1. El modificador nonReentrant

    Esto bloquea el contrato durante la ejecución, impidiendo que se vuelva a entrar en cualquier función marcada con este modificador. Simple pero efectivo.

  2. El Patrón de Comprobaciones- Efectos- Interacciones

    Este es mi favorito personal. En lugar de:

    // VULNERABLE require(balance > 0); enviar(ether); balance = 0;

    Haz esto:

    // SEGURO require(balance > 0); balance = 0; // Actualiza el estado ANTES de interacciones externas enviar(ether);

    ¡Siempre actualiza tu estado antes de enviar ETH o tokens!

  3. GlobalReentrancyGuard

    Para proyectos con múltiples contratos interactuantes, esto proporciona protección en todo su ecosistema de contratos al utilizar un mecanismo de bloqueo compartido.

Estas técnicas no son solo académicas; han salvado a innumerables proyectos de una ruina financiera completa.

Demasiados desarrolladores todavía piensan "no me pasará a mí" y omiten estas protecciones. No seas esa persona. Cada función que envía ETH o tokens debe implementar al menos uno de estos mecanismos de protección.

Recuerda que, en el desarrollo de contratos inteligentes, la paranoia es una característica, no un defecto. Una protección que se pase por alto podría costarlo todo.

ETH1.94%
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)