Análisis detallado de vulnerabilidades del compilador Solidity y estrategias de prevención

Análisis de vulnerabilidades del compilador Solidity y estrategias de respuesta

El compilador es una de las partes fundamentales de los sistemas informáticos modernos. Es un programa de computadora cuya función principal es convertir el código fuente de un lenguaje de programación de alto nivel, que es fácil de entender y escribir para los humanos, en código de instrucciones que puede ser ejecutado por la CPU de la computadora o por una máquina virtual de bytecode.

La mayoría de los desarrolladores y profesionales de la seguridad suelen centrarse en la seguridad del código de las aplicaciones, pero pueden pasar por alto la seguridad del propio compilador. De hecho, el compilador, como un programa informático, también tiene vulnerabilidades de seguridad, y estas vulnerabilidades pueden representar riesgos de seguridad graves en ciertas circunstancias. Por ejemplo, durante el proceso de compilación y análisis de código JavaScript en el frontend, el navegador puede ser vulnerable a ataques que permiten a los atacantes ejecutar código de forma remota, lo que les permite tomar el control del navegador de la víctima e incluso del sistema operativo.

El compilador de Solidity no es una excepción, existen vulnerabilidades de seguridad en varias versiones diferentes.

Vulnerabilidades del compilador Solidity

El compilador de Solidity tiene la función de convertir el código de contratos inteligentes escrito por los desarrolladores en código de instrucciones (EVM) para la Máquina Virtual de Ethereum, y este código de instrucciones EVM se empaqueta y se sube a Ethereum a través de transacciones, siendo finalmente解析 y ejecutado por la EVM.

Es necesario distinguir entre las vulnerabilidades del compilador de Solidity y las vulnerabilidades de la EVM en sí. Las vulnerabilidades de la EVM se refieren a los problemas de seguridad que surgen cuando la máquina virtual ejecuta instrucciones. Dado que los atacantes pueden subir cualquier código a Ethereum, este código finalmente se ejecutará en cada programa cliente P2P de Ethereum. Si hay vulnerabilidades de seguridad en la EVM, esto afectará a toda la red de Ethereum y podría causar un ataque de denegación de servicio (DoS), incluso permitir que un atacante tome el control total de toda la cadena. Sin embargo, debido a que el diseño de la EVM es relativamente simple y el código central no se actualiza con frecuencia, la probabilidad de que surjan estos problemas es relativamente baja.

Las vulnerabilidades del compilador de Solidity se refieren a problemas que ocurren cuando el compilador convierte Solidity en código EVM. A diferencia de un navegador, que compila y ejecuta Javascript en la computadora del cliente del usuario, el proceso de compilación de Solidity solo se lleva a cabo en la computadora del desarrollador de contratos inteligentes y no se ejecuta en Ethereum. Por lo tanto, las vulnerabilidades del compilador de Solidity no afectan directamente a la red de Ethereum.

Una de las principales amenazas de las vulnerabilidades del compilador de Solidity es que pueden resultar en una discrepancia entre el código EVM generado y las expectativas del desarrollador del contrato inteligente. Dado que los contratos inteligentes en Ethereum generalmente involucran los activos de criptomonedas de los usuarios, cualquier error en un contrato inteligente causado por el compilador podría resultar en la pérdida de activos de los usuarios, lo que llevaría a consecuencias graves.

Los desarrolladores y los auditores de contratos pueden centrarse en problemas de implementación de lógica del código del contrato, así como en problemas de seguridad a nivel de Solidity, como reentradas y desbordamientos de enteros. Sin embargo, es difícil detectar las vulnerabilidades del compilador de Solidity solo a través de la auditoría de la lógica del código fuente del contrato. Es necesario analizar en conjunto versiones específicas del compilador y patrones de código específicos para determinar si un contrato inteligente se ve afectado por vulnerabilidades del compilador.

! Análisis de vulnerabilidades y contramedidas del compilador de Solidity

Ejemplo de vulnerabilidad del compilador de Solidity

A continuación se presentan ejemplos de varios errores reales en compiladores Solidity, mostrando su forma específica, causas y peligros.

SOL-2016-9 HighOrderByteCleanStorage

La vulnerabilidad existe en versiones anteriores del compilador Solidity (>=0.1.6 <0.4.4).

Considera el siguiente código:

solidez contrato C { uint32 a = 0x1234; uint32 b = 0; función f() pública { a += 1; } función run() público ver devuelve (uint) { return b; } }

La variable de almacenamiento b no ha sido modificada, por lo que la función run() debería devolver el valor predeterminado 0. Sin embargo, en la versión del compilador con vulnerabilidades, el código generado devolverá 1.

Sin entender la vulnerabilidad del compilador, es difícil para un desarrollador común detectar el bug existente en el código anterior a través de una simple revisión de código. Este código de ejemplo es bastante simple y puede que no cause un daño especialmente grave. Pero si la variable b se utiliza para la verificación de permisos, contabilidad de activos, etc., esta inconsistencia con lo esperado podría resultar en consecuencias muy graves.

La razón de este fenómeno anómalo radica en que EVM utiliza una máquina virtual basada en pila, donde cada elemento de la pila tiene un tamaño de 32 bytes (, es decir, el tamaño de una variable uint256 ). Por otro lado, cada slot de almacenamiento subyacente también tiene un tamaño de 32 bytes. Sin embargo, el lenguaje Solidity admite tipos de datos como uint32 y otros de menos de 32 bytes. Cuando el compilador maneja variables de este tipo, necesita realizar una operación de limpieza adecuada en su parte alta ( clean up ) para garantizar la corrección de los datos. En la situación descrita, cuando la suma provoca un desbordamiento entero, el compilador no realizó correctamente la limpieza en la parte alta del resultado, lo que llevó a que el bit de 1 en la parte alta se escribiera en el almacenamiento, sobrescribiendo así la variable b que sigue a la variable a, modificando el valor de la variable b a 1.

( SOL-2022-4 InlineAssemblyMemorySideEffects

La vulnerabilidad existe en compiladores de versiones >=0.8.13 <0.8.15. Considere el siguiente código:

solidez contrato C { function f)### public pure returns (uint) { ensamblaje { mstore(0, 0x42) } uint x; ensamblaje { x := mload(0) } return x; } }

El compilador de Solidity no solo traduce el lenguaje Solidity a código EVM, sino que también realiza un análisis profundo del flujo de control y de datos, implementando varios procesos de optimización de compilación para reducir el tamaño del código generado y optimizar el consumo de gas durante el proceso de ejecución. Este tipo de operaciones de optimización son comunes en los compiladores de varios lenguajes de alto nivel, pero debido a la complejidad de las situaciones que deben considerarse, también es fácil que aparezcan errores o vulnerabilidades de seguridad.

La vulnerabilidad del código mencionado proviene de este tipo de operaciones de optimización. Consideremos una situación así: si hay código en una función que modifica los datos en la dirección de memoria 0, pero no hay ningún lugar posterior que use esos datos, en realidad se puede eliminar directamente el código que modifica la memoria 0, ahorrando gas y sin afectar la lógica del programa posterior.

Esta estrategia de optimización en sí misma no tiene problemas, pero en la implementación del código del compilador Solidity, dicha optimización solo se aplica dentro de un único bloque de assembly. En el código de ejemplo anterior, la escritura y el acceso a la memoria 0 se encuentran en dos bloques de assembly diferentes, mientras que el compilador solo ha realizado un análisis de optimización en el bloque de assembly individual. Dado que no hay ninguna operación de lectura después de escribir en la memoria 0 en el primer bloque de assembly, se determina que esta instrucción de escritura es redundante y se elimina, lo que genera un error. En la versión con vulnerabilidad, la función f( devolverá el valor 0, cuando en realidad el código anterior debería devolver el valor correcto 0x42.

) SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

La vulnerabilidad afecta a los compiladores de versiones >= 0.5.8 < 0.8.16. Considere el siguiente código:

solidez contrato C { function f(uint8) calldata a### public pure returns (string memory[4] { return string)abi.encode(a)(; } }

Normalmente, la variable a devuelta por el código anterior debería ser "aaaa". Pero en la versión con vulnerabilidades, devolverá una cadena vacía "".

La causa de esta vulnerabilidad es que Solidity realizó una operación abi.encode en un array de tipo calldata, limpiando incorrectamente algunos datos, lo que llevó a la modificación de otros datos adyacentes, causando una inconsistencia en los datos después de la codificación y decodificación.

Es importante notar que, al realizar llamadas externas y emitir eventos, Solidity codifica implícitamente los parámetros con abi.encode, por lo que la probabilidad de que aparezca el código de vulnerabilidad mencionado es mayor de lo que podría parecer a simple vista.

Análisis de vulnerabilidades del compilador Solidity y medidas de respuesta

Consejos de seguridad

Basado en el análisis del modelo de amenaza de vulnerabilidades del compilador Solidity y la revisión de vulnerabilidades históricas, se proponen las siguientes recomendaciones para desarrolladores y personal de seguridad.

Para los desarrolladores:

  • Utiliza una versión más reciente del compilador de Solidity. Aunque las versiones nuevas también pueden introducir nuevos problemas de seguridad, los problemas de seguridad conocidos suelen ser menos que en las versiones anteriores.

  • Mejorar los casos de prueba unitarios. La mayoría de los errores a nivel de compilador pueden causar que los resultados de ejecución del código no coincidan con lo esperado. Este tipo de problemas son difíciles de detectar mediante la revisión del código, pero son fáciles de exponer en la fase de pruebas. Por lo tanto, al aumentar la cobertura del código, se pueden evitar al máximo este tipo de problemas.

  • Intenta evitar el uso de ensamblador en línea, la codificación y decodificación de abi para arreglos multidimensionales y estructuras complejas, y operaciones complejas en general. Evita el uso ciego de nuevas características del lenguaje y funciones experimentales sin una necesidad clara. Según el análisis de vulnerabilidades históricas, la mayoría de las vulnerabilidades están relacionadas con operaciones como el ensamblador en línea y los codificadores de abi. Los compiladores tienden a tener más errores al manejar características complejas del lenguaje. Por otro lado, los desarrolladores también pueden caer en malentendidos al usar nuevas características, lo que lleva a problemas de seguridad.

Para el personal de seguridad:

  • Al auditar la seguridad del código Solidity, no se deben pasar por alto los riesgos de seguridad que pueden introducirse a través del compilador de Solidity. El elemento de verificación correspondiente en la Clasificación de Debilidades de Smart Contract)SWC( es SWC-102: Versión de Compilador Obsoleta.

  • En el proceso de desarrollo interno de SDL, se insta al equipo de desarrollo a actualizar la versión del compilador de Solidity y se puede considerar la introducción de una verificación automática de la versión del compilador en el proceso de CI/CD.

  • Pero no hay que entrar en pánico excesivo por las vulnerabilidades del compilador; la mayoría de las vulnerabilidades del compilador solo se activan en patrones de código específicos, y no significa que un contrato compilado con una versión vulnerable del compilador tenga necesariamente un riesgo de seguridad. El impacto real en la seguridad debe evaluarse específicamente según las circunstancias del proyecto.

Algunos recursos útiles:

  • Alertas de seguridad publicadas regularmente por el equipo de Solidity:

  • Lista de errores actualizada regularmente en el repositorio oficial de Solidity:

  • Lista de errores del compilador de las diferentes versiones:

  • En Etherscan, en la página de Contrato - el ícono de triángulo con signo de exclamación en la esquina superior derecha del código puede alertar sobre vulnerabilidades de seguridad presentes en la versión actual del compilador.

Resumen

Este artículo comienza con los conceptos básicos de los compiladores, presenta las vulnerabilidades del compilador de Solidity y analiza los riesgos de seguridad que pueden surgir en un entorno de desarrollo de Ethereum. Finalmente, se ofrecen varias recomendaciones prácticas de seguridad para desarrolladores y personal de seguridad.

![Análisis de vulnerabilidades del compilador Solidity y medidas de respuesta])https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(

ETH1.74%
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
  • 5
  • Compartir
Comentar
0/400
ZenZKPlayervip
· 07-30 05:45
La vulnerabilidad de desbordamiento es un poco molesta.
Ver originalesResponder0
OffchainWinnervip
· 07-30 00:55
No tengo tiempo para los errores al escribir código.
Ver originalesResponder0
OnchainSnipervip
· 07-30 00:47
¿El compilador se ha estrellado? Ya me ha pasado antes.
Ver originalesResponder0
UnluckyValidatorvip
· 07-30 00:44
Los compiladores tienen vulnerabilidades, asustando a la gente.
Ver originalesResponder0
LiquiditySurfervip
· 07-30 00:41
Llama a los desarrolladores a que arreglen los fallos rápidamente.
Ver originalesResponder0
Opere 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)