Smart-contracts

Seguridad y auditorias en smart contracts

Los smart contracts (contratos inteligentes) son programas que se ejecutan en una plataforma blockchain cuando se cumplen ciertas condiciones definidas en los contratos. Estos contratos se han vuelto fundamentales en los ecosistemas de las criptomonedas y proyectos blockchain, ya que permiten automatizar y garantizar la ejecución de acuerdos sin la necesidad de intermediarios.

El presente artículo tiene como objetivo analizar la seguridad de estos contratos desde el punto de vista del desarrollador, analizando las principales vulnerabilidades que se pueden producir en estas aplicaciones. Un error o una vulnerabilidad en un contrato inteligente puede resultar en la pérdida de activos digitales, violación de la privacidad o incluso la manipulación de un sistema descentralizado.

Introducción al OWASP Smart Contract Top 10

El proyecto OWASP Smart Contract Top 10 [1] tiene como objetivo ofrecer a los desarrolladores y a los equipos de seguridad información sobre las 10 principales vulnerabilidades encontradas en los contratos inteligentes, que se pueden resumir en los siguientes:

  • Reentrancy Attacks (Ataques de reentrada): Vulnerabilidad que se produce cuando un atacante puede llamar repetidamente a una función dentro de un contrato inteligente, aprovechando el hecho de que el estado del contrato no se ha actualizado como se esperaba.
  • Integer Overflow and Underflow (Desbordamiento de enteros). Esta vulnerabilidad se produce cuando las operaciones aritméticas exceden el tamaño máximo o mínimo que una variable de tipo entero puede contener, lo que hace que el valor se ajuste al extremo opuesto
  • Timestamp Dependence (Dependencia del timestamp). Un contrato podría ser vulnerable si el comportamiento del mismo depende de la marca de tiempo del bloque en el que está incluido. Esto se debe a que los mineros tienen cierto grado de control sobre la marca de tiempo del bloque.
  • Access Control Vulnerabilities (Vulnerabilidades de control de acceso). La falta de controles de acceso adecuados puede permitir a cualquiera realizar operaciones críticas, como transferencias de activos, sin necesidad de la autenticación y autorización adecuadas.
  • Front running. Es una vulnerabilidad donde un atacante puede observar una transacción pendiente y luego su propia transacción con una tarifa de gas más alta, incentivando a los mineros a incluirla primero en la cadena de bloques. Esto es posible en redes públicas de blockchain como Ethereum [2, 3], donde los datos de las transacciones son accesibles públicamente antes de ser extraídos.
  • Denial of Service (DoS) Attacks (Ataques de Denegación de Servicio). Los ataques DoS tienen como objetivo hacer que un contrato no esté disponible para ser ejecutado dentro de la cadena de bloques. En los contratos inteligentes, en el caso de redes como Ethereum [2, 3] esto podría lograrse consumiendo todo el gas disponible o provocando que las transacciones fallen de forma ilimitada.
  • Logic Errors (Errores de lógica). Son un tipo de error en la programación de software que no producen error o excepciones en tiempo de ejecución, pero que podrían hacer que el contrato se comporte de forma incorrecta. Estos errores, a menudo son difíciles de detectar porque el código se ejecuta, pero no produce los resultados esperados debido a un error en la lógica de programación.
  • Insecure Randomness. Se refiere a una vulnerabilidad en la que la generación de números aleatorios en un sistema o aplicación no es lo suficientemente segura o impredecible. Esto puede ser especialmente problemático en el contexto de la criptografía y la seguridad de aplicaciones, ya que una aleatoriedad insuficiente puede hacer que los datos y claves sean predecibles y, por lo tanto, vulnerables a ataques.
  • Gas Limit Vulnerabilities (Vulnerabilidades de límite de gas). En el caso de la blockchain de Ethereum [3]  cada bloque tiene definido un límite de gas, lo que restringe la cantidad de operaciones que puede incluir ese bloque. Si una función dentro de un contrato requiere más gas que este límite, podría congelar los fondos de ese contrato.
  • Unchecked External Calls. En Ethereum [2], cuando un contrato llama a otro contrato, el contrato llamado puede fallar sin generar una excepción. Si el contrato de llamada no verifica el resultado de la llamada, podría asumir que la llamada fue exitosa, incluso si no lo fue.

Lenguaje de programación solidity para smart contracts

Solidity [4] es un lenguaje de programación específicamente diseñado para escribir contratos inteligentes en plataformas de cadena de bloques, como Ethereum. Algunas de las implicaciones de utilizar Solidity para escribir smart contracts incluyen:

  • Seguridad: Solidity está diseñado con características de seguridad que ayudan a prevenir vulnerabilidades comunes en los contratos inteligentes, como ataques de reentrancia y desbordamientos de enteros. Sin embargo, los desarrolladores deben tener un profundo entendimiento de las mejores prácticas de seguridad y las peculiaridades del lenguaje para evitar errores costosos.
  • Ejecución en la cadena de bloques: Los contratos inteligentes escritos en Solidity se ejecutan en la cadena de bloques y forman parte de su estado. Esto implica que una vez desplegados, los contratos inteligentes son inmutables y pueden interactuar con otros contratos y usuarios en la cadena de bloques.
  • Interoperabilidad: Solidity es ampliamente utilizado en la comunidad de Ethereum y es compatible con una variedad de herramientas y bibliotecas que facilitan el desarrollo de contratos inteligentes. Esto permite una mayor interoperabilidad entre diferentes aplicaciones descentralizadas (dApps) que se ejecutan en la misma cadena de bloques.
  • Complejidad: Es importante tener en cuenta que Solidity puede ser complejo de dominar, especialmente para aquellos que no tienen experiencia previa en desarrollo de contratos inteligentes o programación en blockchain. Requiere un entendimiento profundo de conceptos como transacciones, gas, almacenamiento de datos y estructuras de control específicas de Solidity.
  • Evolución continua: Solidity es un lenguaje en constante evolución, con actualizaciones frecuentes y nuevas características introducidas regularmente. Los desarrolladores deben mantenerse actualizados con las últimas versiones y prácticas recomendadas para aprovechar al máximo el potencial del lenguaje y garantizar la seguridad y eficacia de sus contratos inteligentes.

Ethereum Virtual Machine (EVM)

La Ethereum Virtual Machine (EVM) es una parte fundamental del ecosistema de Ethereum y es esencial para el funcionamiento de la red. Entre las principales características de la Ethereum Virtual Machine podemos destacar:

  • Ejecución de contratos inteligentes: La EVM es una máquina virtual Turing completa que ejecuta los contratos inteligentes escritos en lenguajes como Solidity. Los contratos inteligentes son programas informáticos que se ejecutan en la cadena de bloques y permiten la automatización de acuerdos y transacciones sin la necesidad de intermediarios.
  • Seguridad y confiabilidad: La EVM está diseñada para garantizar la seguridad y la confiabilidad de los contratos inteligentes. Utiliza un modelo de ejecución determinista, lo que significa que todas las transacciones se ejecutan de la misma manera en todos los nodos de la red, lo que garantiza la consistencia y la integridad de los resultados.
  • Gas y costo de transacción: La EVM utiliza una unidad de medida llamada «gas» para calcular el costo de ejecutar operaciones y contratos en la red. Los usuarios deben pagar una cierta cantidad de gas para ejecutar transacciones y contratos, y el costo total de una transacción se calcula multiplicando el precio del gas por el consumo de gas de la transacción.
  • Interoperabilidad: La EVM es compatible con una amplia variedad de lenguajes de programación y herramientas de desarrollo, lo que permite a los desarrolladores crear una amplia gama de aplicaciones descentralizadas (dApps) y contratos inteligentes en la plataforma Ethereum.

En la siguiente imagen vemos la arquitectura de la EVM y los diferentes elementos que la componen para ejecutar los smart contracts:

Referencia:https://www.researchgate.net/publication/366170214_Fundraising_Tracking_System_Using_Blockchain

El papel del desarrollador en los smart contracts

Como hemos comentado, los errores en la lógica de programación son un tipo de error en la programación de software que no producen fallos o excepciones en tiempo de ejecución, pero que causan un comportamiento incorrecto o no deseado en la aplicación. Estos errores son difíciles de detectar porque el código se ejecuta sin problemas, pero no produce los resultados esperados debido a errores en la lógica de programación. A continuación, comentamos algunos ejemplo de errores de lógica:

  • Errores de lógica de negocio: No reflejar correctamente las reglas de negocio en el código, puede llevar a comportamientos incoherentes o incorrectos en una aplicación.
  • Orden de operaciones incorrecto: Cuando se realizan cálculos o acciones en un orden incorrecto, lo que lleva a resultados incorrectos. Por ejemplo, realizar una suma antes de una multiplicación cuando la lógica requería lo contrario.
  • Condicionales incorrectos: Usar una condición incorrecta en una estructura condicional (como un if o un switch) que no refleja la intención del programa. Esto puede llevar a que se tomen decisiones incorrectas.
  • Bucles infinitos: Crear bucles que no terminan cuando deberían o que terminan antes de lo debido debido a una condición incorrecta.
  • Asignación de variables incorrectas: Asignar un valor incorrecto a una variable, lo que puede afectar el funcionamiento de otras partes del código.
  • Errores de cálculo: Realizar cálculos incorrectos, como errores en las fórmulas matemáticas o lógicas utilizadas en la aplicación.

La mayoría de estos errores son especialmente difíciles de depurar porque el código no devuelve excepciones ni errores, sin embargo la aplicación se ejecuta sin problemas en términos de funcionamiento. Para encontrar y corregir estos errores, normalmente se requiere una comprensión profunda del diseño y la lógica de la aplicación, así como realizar pruebas exhaustivas y de revisión de código por parte de desarrolladores y equipos de calidad.

Las técnicas de depuración, el análisis de flujo del programa y la revisión de código son herramientas útiles para detectar y solucionar errores en la lógica del programa. Además, la adopción de buenas prácticas de diseño de código pueden ayudar a prevenir la aparición de estos errores.

De esta forma, el papel del desarrollador en la creación y gestión de smart contracts es fundamental para garantizar que estos contratos inteligentes sean seguros, funcionales y cumplan con los requisitos del proyecto. Aquí tienes un resumen de las responsabilidades y tareas del desarrollador en relación con los smart contracts:

  • Diseño y planificación:
      • Identificación de los requisitos del contrato inteligente, incluyendo sus funciones, parámetros y reglas de negocio.
      • Diseño de la arquitectura y la estructura del contrato inteligente.
      • Planificación de las interacciones con otros contratos y componentes del ecosistema blockchain.
  • Desarrollo y codificación:
      • Escritura del código del contrato inteligente en un lenguaje de programación compatible con la plataforma blockchain (por ejemplo, Solidity en Ethereum).
      • Implementación de las funciones y lógica del contrato, incluyendo la gestión de datos y la interacción con otros contratos o activos.
      • Uso de buenas prácticas de programación y patrones de diseño para garantizar la seguridad y eficiencia del contrato.
  • Auditorías de seguridad:
      • Identificación y mitigación de vulnerabilidades de seguridad como las mencionadas en el OWASP Smart Contract Top 10 [1].
      • Realización de auditorías de seguridad o revisiones de código por parte de expertos en seguridad.
      • Implementación de patrones de seguridad recomendados, como el uso de la librería OpenZeppelin [4,5,6].
  • Pruebas unitarias y de integración:
      • Creación y ejecución de pruebas unitarias y pruebas de integración para verificar el comportamiento y la funcionalidad del contrato inteligente.
      • Pruebas exhaustivas para simular escenarios de uso real y comprobar el cumplimiento de los requisitos.
  • Despliegue y gestión:
    • Despliegue del contrato inteligente en la blockchain de destino.
    • Gestión de las direcciones de contrato y las actualizaciones.
    • Establecimiento de políticas de actualización y gobernanza.
  • Documentación:
    • Creación de documentación técnica y de usuario para el contrato inteligente.
    • Descripción de las funciones, parámetros, eventos y políticas de uso.
    • Documentación de los procedimientos de actualización y mantenimiento.

 

En resumen, el papel del desarrollador en los smart contracts requiere una comprensión profunda de la plataforma blockchain, así como habilidades de programación, seguridad y buenas prácticas de desarrollo. La seguridad es particularmente crítica en la creación de smart contracts, ya que cualquier vulnerabilidad podría resultar en la pérdida de activos o datos, por lo que la auditoría y la revisión de código por parte de expertos en seguridad son pasos importantes en el proceso de desarrollo.

Herramientas para realizar auditorías de seguridad

Existen varias herramientas y servicios que podemos utilizar para llevar a cabo auditorías y pruebas de seguridad en smart contracts. Estas herramientas ayudan a identificar vulnerabilidades y errores en el código antes de su implementación en la blockchain. Entre las principales herramientas y servicios podemos destacar:

  • Slither[7]: Herramienta de código abierto diseñada para la detección de vulnerabilidades en contratos inteligentes de Ethereum. Proporciona análisis estático y tiene la capacidad de identificar problemas como ataques de reentrada y de desbordamiento.
  • Securify[8]: Herramienta de análisis de seguridad para contratos inteligentes en Ethereum que utiliza análisis estáticos para detectar vulnerabilidades.
  • Consensys Diligence[9]: Ofrecen auditorías de seguridad profesionales y tienen una amplia experiencia en la revisión de smart contracts.
  • Quantstamp[10]: Firma de auditorías de seguridad que utiliza análisis estáticos y dinámicos para identificar vulnerabilidades en contratos inteligentes.

Entre las principales características que ofrecen estas herramientas podemos destacar:

  • Análisis de vulnerabilidades: Utilizan un conjunto de reglas predefinidas para buscar posibles vulnerabilidades en el código. Puede detectar problemas como el desbordamiento de enteros, condiciones de carrera, problemas de acceso a la información y otras vulnerabilidades comunes.
  • Integración con herramientas de desarrollo: Se pueden integrar fácilmente en el flujo de trabajo de desarrollo de smart contracts. Pueden ser utilizados desde la línea de comandos, como una biblioteca en otro programa o incluirse en nuestro pipeline de desarrollo.
  • Informes detallados: Proporcionan informes detallados sobre las vulnerabilidades y debilidades encontradas en el código. Estos informes incluyen descripciones de los problemas, ubicaciones exactas en el código fuente y recomendaciones para corregirlos.

Referencias:

[1] https://owasp.org/www-project-smart-contract-top-10/

[2] https://ethereum.org/es

[3] https://ethereum.org/es/developers/docs/gas/#what-is-gas

[4] https://solidity-es.readthedocs.io

[5] https://www.openzeppelin.com/contracts

[6] https://github.com/OpenZeppelin/openzeppelin-contracts

[7] https://github.com/crytic/slither

[8] https://github.com/eth-sri/securify2

[9] https://consensys.io/diligence

[10] https://quantstamp.com

LinkedIn
Twitter
Facebook
WhatsApp
0 0 votos
Calificación del artículo
Suscribir
Notificar de
guest
0 Comentarios
Comentarios en línea
Ver todos los comentarios
Metafrase
Contacto

© 2024, Metafrase SLU

0
Me encantaría conocer tu opinión, por favor comenta.x
()
x