Solidity: Vulnerabilidades Con Variables Globales

Las variables globales en Solidity son fundamentales en el desarrollo de smart contracts, pero pueden exponer graves vulnerabilidades si no se utilizan correctamente.

Cómo realizar la identificación del usuario en smart contracts

Es frecuente la necesidad de validar los permisos del usuario y para esto se utiliza la dirección de la billetera que emitió la transacción. Hay que tener algunas precauciones al realizar esta identificación.

Solidity permite la captura de la dirección del contrato que hizo la transacción y posteriormente se utiliza este dato para identificar al usuario.

Utilizamos msg.sender para obtener el dato, pero el lenguaje también cuenta con la variable global tx.origin que dependiendo la circunstancia devuelve la misma información.

  • msg.sender = Emisor del mensaje
  • tx.origin = Origen de la transacción

A simple vista, pueden parecer exactamente iguales ambas variables, ya que a la hora de hacer una transferencia de cuenta a cuenta van a devolver el mismo valor. ¿Pero qué pasa si quién realiza la transacción es otro contrato inteligente? Aquí es donde los valores de msg.sender y tx.origin van a diferir.

Esta vulnerabilidad de seguridad puede explotarse realizando transacciones al contrato, desde otro contrato. Al cambiar el valor de tx.origin, el atacante puede acceder a partes de la lógica del contrato que no le corresponde.

Diferencia msg.sender y tx.origin

En conclusión, se debe tener precaución cuando se utiliza tx.origin para identificar y validar al usuario que emite la transacción. En su lugar, es mejor usar msg.sender.

Números aleatorios en Blockchain

Dependiendo de la regla de negocio de nuestro proyecto, podemos tener la necesidad de generar números de forma totalmente aleatoria para determinar al ganador de un sorteo o lotería.

En pocas palabras, en Blockchain no existen los números aleatorios. No es posible hacer un Math.random() como en Javascript para obtener un número aleatorio y poder utilizarlo.

Todo en Blockchain es determinista, o sea, toda operación debe tener un resultado predecible. Dado un estado inicial y una acción, siempre se genera el mismo resultado. Esto garantiza que los nodos puedan ponerse de acuerdo a la hora de minar bloques o transacciones y es una de las características principales de cualquier Blockchain.

Problemas frecuentes con la aleatoriedad en Blockchain

Es frecuente el uso de algunas variables globales de Solidity para “simular” un número aleatorio como block.timestamp que nos devuelve una etiqueta de tiempo o block.number que devuelve el número del bloque actual.

Ninguna de las dos opciones es para nada aconsejable, ambas pueden ser manipuladas y predichas por los atacantes.

Si una acción crítica de nuestro contrato depende de un valor aleatorio, debemos buscar alternativas off-chain como Chainlink. Este tipo de servicio se los conoce con el nombre de Oráculos para realizar procesamientos no deterministas fuera de la blockchain y reinsertar ese valor en el contrato cobrando una comisión.

La aleatoriedad en Blockchain es compleja y requiere de desafíos técnicos avanzados para proponer soluciones viables y seguras.

Conclusión

Hemos visto como algunas variables globales en Solidity, como msg.sender, tx.origin o block.timestamp pueden darnos versatilidad en el desarrollo de nuestros contratos, pero pueden exponer vulnerabilidades no deseadas en el mismo.


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