Seguridad de contratos inteligentes basados en Blockchain I

Recientemente, la tecnología blockchain ha sido promovida como un elemento de cambio para muchas industrias. La tecnología de contabilidad distribuida que surgió de Bitcoin tiene aplicaciones prometedoras más allá de las monedas digitales.

Uno de los casos de uso más prometedores de la tecnología blockchain es la elaboración de contratos inteligentes.

Los contratos inteligentes son contratos autoejecutables, en los que los términos se especifican en el código. Básicamente, esto significa implementar contratos legales en código de ordenador, que los ejecuta automáticamente.

Si bien el concepto existe desde hace tiempo, al menos desde que Nick Szabo escribió el concepto en 1996, no fue hasta la llegada del blockchain de Ethereum con la capacitad de expresar cualquier computación (“Turing complete”), que el uso del contrato inteligente se hizo común.

Los contratos Ethereum existen en direcciones de contrato y pueden invocarse mediante llamadas de transacción.

Ejecutar contratos escritos en código y almacenados en un blockchain público inmutable crea ciertos riesgos y problemas, que discutiremos de forma general en esta publicación. En una próxima segunda parte, veremos ejemplos más específicos de vulnerabilidades de seguridad de contratos inteligentes.

Contrato inteligente

¿Código es ley?

Una interpretación literal de la idea del contrato inteligente lleva al paradigma “Código es Ley”, lo que significa que los contratos inteligentes son vinculantes y se interpretan como si fueran documentos legales. Cualquier ingeniero de software consciente de la imposibilidad de crear un código completamente libre de errores se echaría las manos a la cabeza ante la idea de que un programa informático sea legalmente vinculante. Hay una serie de problemas obvios:

  1. El código contiene errores. Es extremadamente difícil escribir código libre de errores e incluso si se toman todas las precauciones posibles, siempre habrá rutas de ejecución inesperadas o posibles vulnerabilidades en un software razonablemente complejo.
  2. Los contratos legales están sujetos a interpretación y arbitraje. Es muy difícil crear contratos herméticos. En cualquier contrato grande, los errores tipográficos pueden deslizarse y algunas cláusulas deben ser interpretadas y arbitradas. Eso es lo que hacen los tribunales en caso de disputa. Si en un contrato legal el precio de venta se especifica como $100 en 39 de 40 páginas y en una página se ingresa un cero adicional, un tribunal dictaminará “en el espíritu del contrato”. Un ordenador simplemente ejecuta la cláusula tal como está escrita. La inmutabilidad del blockchain se suma a este problema, ya que los contratos no se pueden modificar fácilmente.
  3. 3. Los ingenieros de software no son expertos legales y viceversa. . Se requiere un conjunto de habilidades diferente para redactar un buen contrato, no necesariamente compatible con la redacción de un buen programa informático.

Dos Ejemplos de Ataques a Contratos Inteligentes de Alto-perfil

El ataque DAO

Mucho se ha dicho sobre este caso, que no reiteraremos aquí. Una buena descripción del ataque y las consecuencias se puede encontrar aquí.

En resumen, en junio de 2016, un atacante logró desviar una gran cantidad de fondos de fuente colectiva (3.5M ETH, aproximadamente 15% del total de ETH en ese momento) en su propio contrato derivado (child DAO), en el cual los fondos se bloquearon durante 28 días, lo que llevó a una carrera a contra reloj para encontrar una solución.

El punto importante a tener en cuenta en este caso, es que el contrato fue atacado haciéndolo comportarse de una manera inesperada. En este caso particular, las vulnerabilidades de código reentrante se explotaron. Veremos este tipo de vulnerabilidad en detalle en una secuela a esta publicación.

El hackeo de parity

De hecho, este fue el segundo “ataque” al contrato de monedero multi-firma proporcionado por Parity. El contrato de monedero múltiple, utilizado por muchas start-ups, tenía la mayor parte de su lógica implementada en un contrato de biblioteca. Cada monedero consistía en un contrato de cliente ligero que se conectaba a este único punto de fallo.

Arquitectura de parity multisig

Hubo un error crucial en el contrato de biblioteca, que consistía en una función de inicialización que podía llamarse una vez.

En noviembre de 2017, alguien sí inicializó el contrato y al hacerlo se convirtió en el propietario del contrato. Esto le permitió invocar funciones de propietario, un privilegio que usó para llamar a la siguiente función:

// kills the contract sending everything to `_to`.
function kill(address _to) onlymanyowners(sha3(msg.data)) external {
    suicide(_to);
}

Esto es el equivalente de un botón de autodestrucción, que hace que el contrato sea inútil. Llamar a esta función provocó que todos los fondos de los contratos del cliente se congelaran, probablemente para siempre.

Al momento de escribir este artículo, aún no está claro si el incidente constituyó un ataque deliberado o si fue accidental, con el perpetrador afirmando acciones accidentales.

Ambos ataques muestran que incluso los contratos relativamente simples, escritos por los principales actores del ecosistema de blockchain, son propensos a errores básicos con graves consecuencias.

¿Qué se puede hacer?

La historia reciente ha demostrado que la ejecución de contratos inteligentes en blockchains públicos es peligrosa y en ningún lugar lo suficientemente segura como para sustituir los sistemas legales más tradicionales con su lenguaje preciso, espacio para la interpretación y el arbitraje.

Esto no significa que debamos abandonar los contratos inteligentes. Son herramientas extremadamente útiles y abren aplicaciones interesantes. Sin embargo, no deberíamos considerarlos sustitutos de contratos legalmente vinculantes, sino herramientas complementarias para la automatización.

Además, debemos tomar las siguientes precauciones para evitar vulnerabilidades:

  • Usar estándares de facto de código abierto y aceptados por la comunidad para los contratos de biblioteca, tales como los contratos de Open Zeppelin.
  • Utilizar los patrones recomendados y las pautas de mejores prácticas, como los que proporciona Consensys.
  • Considerar contratar una auditoría de sus contratos inteligentes por un proveedor acreditado.

En una próxima publicación de esta serie, veremos algunas vulnerabilidades conocidas, incluidos ejemplos de código, y cómo prevenirlas.