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 mensajetx.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.
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.