Solidity: Vulnerabilidades De AlmacenamientO

Los problemas de seguridad pueden estar relacionados con varios aspectos del desarrollo de contratos inteligentes. Uno de ellos es el tipo de variable para almacenar datos.

Problema con las variables numéricas: overflow y underflow

Un problema de seguridad relacionado con el uso de variables enteras es el conocido como Overflow y Underflow.

Cuando una variable entera llega al límite máximo que puede representar y se le suma uno, se reinicia a cero. Caso contrario, lo mismo ocurre cuando se encuentra en su límite mínimo y se le resta uno, pasa al valor máximo que puede representar.

Por ejemplo, si una variable puede almacenar como máximo el valor 999, al sumarle uno pasará a 000 y si le restamos uno a este vuelve a 999.

Este es un problema grave de seguridad ya que si los valores se tratan de montos económicos, un atacante puede provocar que el saldo de una cuenta pase al máximo posible y robe todos los fondos de un contrato.

Evitando el overflow y el underflow

Afortunadamente, el problema ha sido resuelto a partir de la versión 0.8.0 del compilador de Solidity. Si ocurriese uno de estos tipos de errores, se lanzará una advertencia de error evitando que se pueda explotar la vulnerabilidad.

Ten en cuenta la compatibilidad hacia atrás. Contratos inteligentes que fueron desarrollados con versiones anteriores a la 0.8.0 aún tienen este problema, que puede ser resulto con librerías que hagan las respectivas validaciones como Math de OpenZeppelin.

Ten presente este problema si trabajas con versiones del compilador más antiguas y variables numéricas, tanto con signo como sin signo o de cualquier longitud.

Tipos de visibilidad en Solidity y variables privadas

Los diferentes tipos de visibilidades que puedes declarar en un contrato inteligente pueden tener diversas vulnerabilidades. Estas no necesariamente pueden ser un problema, pero debes conocerlas para evitar ataques.

Solidity es un lenguaje de programación orientado a objetos y como tal, permite configurar la visibilidad de los atributos y métodos de todo el contrato. Podemos declarar atributos y funciones públicas, privadas, internas y externas.

  • Public: variables y métodos totalmente accesibles.
  • Private: accesible únicamente a través de una función dentro del contrato.
  • Internal: métodos accesibles solo a través de una función incluida en el mismo contrato. No podrán ser accedidas desde llamadas externas de otros contratos.
  • External: caso contrario a internal, son métodos a los cuales puedes acceder desde otro contrato, pero no desde el mismo.

De alguna forma u otra, todo en Blockchain es accesible. No existe posibilidad de bloquear por completo un dato y ocultarlo.

La visibilidad por defecto de una variable es internal mientras que la visibilidad de las funciones es public. Si declaras variables del tipo public, al compilar el contrato inteligente se crearán métodos del tipo view para obtener sus valores.

Problemas con la visibilidad con las variables privadas

Si decidimos declarar variables privadas, tienes que saber que es posible el acceso a estos datos de todos modos.

contract Privado {

  uint private secret_1;  // Índice 0
  uint private secret_2;  // índice 1

  constructor(valor_1: uint, valor_2: uint) {
    secret_1 = valor_1;
    secret_2 = valor_2;
  }
}

Las variables privadas de un contrato pueden ser accedidas a través de su índice en memoria con ayuda de librerías como Truffle que permiten acceder a los datos privados de un contrato inteligente con métodos como web3.eth.getStorageAt("<contract_address>", index). El mismo devolverá el valor de la variable codificado en Base64, muy fácilmente decodificable para obtener su verdadero valor.

En síntesis, utiliza los diferentes tipos de visibilidad que Solidity tiene para ofrecer dependiendo la regla de negocio, pero sabiendo que todos los datos son visibles de alguna u otra manera. No guardes contraseñas o secretos en variables privadas, no han sido implementados para eso.

Conclusión

Las vulnerabilidades en el almacenamiento de Solidity pueden comprometer la seguridad de los contratos inteligentes. Evitar problemas como overflow/underflow requiere usar versiones modernas del compilador o librerías externas. Además, la visibilidad de variables no garantiza privacidad absoluta; nunca almacenes información sensible en contratos. Comprender y aplicar estas prácticas es esencial para desarrollar smart contracts seguros y confiables.


Post creado en colaboración con el Curso de Seguridad de Smart Contracts de Platzi.