---
title: "Vulnerabilidad de repetición de firmas ERC-1271"
description: "El 27 de octubre de 2023, Alchemy descubrió una vulnerabilidad de repetición de firmas en contratos ERC1271 que afectó a un gran número de smart contract accounts (SCA) y generó riesgos al interactuar con varias aplicaciones."
---

# Vulnerabilidad de repetición de firmas ERC-1271

<ImageBlock
  src="https://media.alchemy.com/1711750158-smart-contract.png"
  alt="Vulnerabilidad de Repetición de Firma en Smart Contract Account"
  width={2400}
  height={1260}
  caption="Vulnerabilidad de Repetición de Firma en Smart Contract Account"
  priority
/>

El 27 de octubre de 2023, Alchemy descubrió una vulnerabilidad de repetición de firma de contrato ERC1271 que afectó a una gran cantidad de cuentas de contrato inteligente \(SCA\), y que generó riesgos al interactuar con varias aplicaciones. Las SCA afectadas incluían nuestra LightAccount y la SmartAccount de OKX, y las interacciones con aplicaciones que identificamos como riesgosas incluían Permit2 y [Cowswap](https://www.alchemy.com/dapps/cowswap). Rápidamente reportamos este problema a las distintas SCA y aplicaciones afectadas, y descubrimos que [curiousapple](https://twitter.com/0xcuriousapple), un investigador de seguridad independiente, había encontrado la misma vulnerabilidad un mes antes. Colaboramos con curiousapple, [Frangio](https://twitter.com/frangio_) \(autor de ERC1271\), el equipo de ERC4337 y otros expertos técnicos en SCA para desarrollar una solución. A la fecha, no hay fondos en riesgo y el impacto en las aplicaciones es bastante limitado. Todas las SCA involucradas han reconocido el riesgo o ya han lanzado una solución.

## Detalles técnicos

### Firmas de contrato ERC-1271

En Ethereum y en todas las cadenas basadas en Ethereum Virtual Machine \(EVM\), existen dos tipos de cuentas: cuentas de propiedad externa \(EOA\) y contratos inteligentes. Las EOA pueden autenticar mensajes firmando con la clave privada de su par de claves ECDSA asociado. Sin embargo, dado que a los contratos inteligentes se les asigna una dirección predeterminada durante su creación, no tienen acceso directo a una clave privada para firmar mensajes.

Para resolver este problema, en 2018 se propuso el estándar de firmas de contrato [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271). Con este estándar, los contratos inteligentes pueden implementar restricciones/verificaciones sobre lo que constituye una firma válida, y las aplicaciones pueden llamar a `contract.isValidSignature` para verificar si una acción fue autorizada por el contrato inteligente.

En el contexto de las cuentas de contrato inteligente \(SCA\), ERC-1271 resulta muy útil, ya que permite que los usuarios de SCA utilicen aplicaciones basadas en firmas de la misma manera que lo hacen las EOA. Estas aplicaciones incluyen [OpenSea](https://www.alchemy.com/dapps/opensea) y gran parte de DeFi (que depende del flujo de aprobación de tokens → llamada).

### Vulnerabilidad de repetición de firma ERC1271

La mayoría de las SCA implementan ERC-1271 usando la implementación de referencia mostrada arriba. Desde el punto de vista de ingeniería, es una implementación liviana, y facilita mucho las integraciones de clientes, ya que podíamos reutilizar métodos como `signTypedData`, `signMessage`, `eth\_signTypedData\_v` y `personal\_sign` de la misma forma en que se usan para las EOA.

Sin embargo, en el caso de que la misma dirección sea propietaria de varias SCA, y la aplicación no incluya la dirección de origen de la interacción, la misma firma sería válida en ambas cuentas para esa aplicación.

Como esta vulnerabilidad solo es posible con una combinación de SCA y aplicación, la gravedad de la vulnerabilidad depende de con qué aplicaciones funcione esta interacción. La primera aplicación que analizamos fue [Permit2](https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2), infraestructura pública construida por Uniswap que mejora la seguridad y la UX de los flujos de aprobación de tokens [ERC20](https://www.alchemy.com/overviews/erc20-solidity) en toda la industria, y que por lo tanto es ampliamente utilizada hoy en día.

El bloque de código a continuación muestra las estructuras (structs) que cubre la firma de Permit2. Cabe destacar que `address owner`, la dirección desde la que se extraen los tokens, no está cubierta por la firma y se pasa como argumento en las llamadas a Permit2.

La forma en que un atacante aprovecharía esta vulnerabilidad de repetición de firma es la siguiente:

1. Bob solicita un pago de tokens `X` a Alice, quien posee `n` SCA, y pide que se haga mediante Permit2.
1. Después de que Alice firma el primer permit, Bob puede repetir ese permit en todas las SCA de Alice para recibir un total de `n X` tokens.

<ImageBlock
  src="https://media.alchemy.com/1711750457-diagram-of-bob-s-attack-on-alice-that-owns-2-scas.png"
  alt="Diagrama del ataque de Bob a Alice, que posee 2 SCAs"
  width={852}
  height={559}
  caption="Diagrama del ataque de Bob a Alice, que posee 2 SCAs"
/>

Durante este proceso, creamos una prueba de concepto para confirmar esta vulnerabilidad. Se puede encontrar aquí: [**replay-sig-poc**](https://github.com/omgwiNNING/replay-sig-poc)​

## Impacto

Como parte de nuestra investigación, descubrimos que:

1. Múltiples SCA estaban en riesgo.

1. Además de nuestra LightAccount, otras SCA afectadas incluían Kernel de Zerodev ([Kernel](https://github.com/zerodevapp/kernel/blob/main/src/Kernel.sol)), [Biconomy](https://github.com/bcnmy/scw-contracts), [Soul Wallet](https://github.com/SoulWallet/soul-wallet-contract), [EIP4337Fallback](https://github.com/eth-infinitism/account-abstraction/blob/8215b88768d993fb6459c2723d173791a537a2e7/contracts/samples/gnosis/EIP4337Fallback.sol) de eth-infinitism para Gnosis Safes, [AmbireAccount](https://github.com/AmbireTech/wallet/blob/main/contracts/AmbireAccount.sol), [SmartAccount](https://github.com/okx/AccountAbstraction/tree/main/contracts/wallet) de OKX, [BaseWallet](https://github.com/argentlabs/argent-contracts/blob/develop/contracts/wallet/BaseWallet.sol) de Argent, y [Fuse Wallet](https://github.com/fuseio/fuse-wallet-contracts).
1. Múltiples aplicaciones estaban en riesgo:

1. Permit2: las transferencias basadas en firmas se pueden repetir. Sin embargo, la mayor parte del uso de Permit2 va hacia Universal Router, y cualquier forma de aprovechar esto requeriría una vulnerabilidad crítica independiente en Universal Router.
1. Cowswap: las operaciones que usan la ruta ERC-1271 se pueden repetir. La firma cubre `address recipient`, por lo que el riesgo aquí sería, a lo sumo, precios desactualizados y/o algunas pérdidas por MEV.
1. [Gnosis Safe](https://www.alchemy.com/dapps/gnosis-safe) no fue vulnerable a este vector de ataque.

En este punto, divulgamos esto a las SCA y aplicaciones a través de un grupo de Telegram, y descubrimos que curiousapple también había encontrado el mismo problema un mes antes y estaba colaborando con Frangio y otros expertos técnicos en SCA para desarrollar una solución. En resumen, la lista completa de combinaciones afectadas de SCA y aplicaciones identificadas hasta el momento se muestra a continuación:

<ImageBlock
  src="https://media.alchemy.com/1711750508-screenshot-2024-02-06-at-1-59-14-pm-1.png"
  alt="Tabla de smart contract accounts y aplicaciones afectadas por la vulnerabilidad de repetición de firma ERC-1271"
  width={637}
  height={587}
  caption="Impacto: Cuentas y Aplicaciones"
/>

Nota: en el caso de Argent, como es una app móvil y genera el firmante por dispositivo, es imposible que 2 SCA pertenezcan a la misma EOA, por lo que el ataque de repetición de firma no funciona contra Argent. Sin embargo, los proyectos que hacen un fork de los contratos de Argent sin replicar toda su arquitectura podrían estar en riesgo y deberían adoptar la arquitectura de wallet de Argent, o bien lanzar una solución.

## Solución

Se propusieron dos soluciones para las SCA. Los desarrolladores de SCA deben tener en cuenta que deberían implementar una de estas dos soluciones para prevenir el ataque de repetición descrito anteriormente:

Ambas soluciones prevendrían el ataque de repetición de firma ERC-1271. La segunda solución es más liviana, pero implicaría que los clientes de wallet tendrían que mostrar a los usuarios un hash opaco para firmar. La primera solución es un camino más sencillo para garantizar que las firmas no sean opacas para el usuario, razón por la cual optamos por esa primera solución para LightAccount. La mayoría de las demás SCA también optaron por la misma solución.

## Agradecimientos

¡Muchas gracias a OKX por pagar una recompensa por bug (bug bounty) a Howy por este problema!

¡Felicitaciones a [curiousapple](https://twitter.com/0xcuriousapple) por recibir recompensas por bugs de Ambire, Instadapp, Biconomy y Cowswap!

Además, un enorme reconocimiento a:

1. [Dror Tirosh](https://twitter.com/drortirosh) por idear el enfoque de solución basado en estructuras EIP-712 que adoptaron la mayoría de las SCA.
1. [Frangio](https://twitter.com/frangio_) por compartir más contexto sobre ERC-1271 y por el gran impulso para actualizar la implementación de referencia de ERC-1271 a través del comité de EIP.
1. [Ivo \(Ambire\)](https://twitter.com/ivshti) por su análisis a fondo de las diferencias de implementación técnica entre las dos soluciones propuestas.
1. [Vectorized](https://twitter.com/optimizoor) por proponer y financiar una recompensa de 0.5 ETH para una implementación de cliente de la solución EIP-712 anidada.
1. [Juno \(ChainLight\)](https://twitter.com/junorouse) por asumir ese desafío, lanzar una [implementación de cliente de la solución EIP712 anidada](https://github.com/junomonster/nested-eip-712) y reclamar la recompensa de Vectorized.
1. [David Eiber](https://twitter.com/eiber_david) por su ayuda para pensar vulnerabilidades relacionadas, indexar las SCA y protocolos afectados, y crear PoC.
1. [Yoav Weiss](https://twitter.com/yoavw) por su ayuda durante todo el proceso, incluyendo ponernos en contacto con investigadores de seguridad y otras SCA y aplicaciones afectadas.
