---
title: "ERC-1271 서명 재전송(replay) 취약점"
description: "2023년 10월 27일, Alchemy는 다수의 스마트 컨트랙트 계정(SCA)에 영향을 미치고 여러 애플리케이션과 상호작용 시 위험을 초래하는 ERC1271 컨트랙트 서명 재전송 취약점을 발견했습니다."
---

# ERC-1271 서명 재전송(replay) 취약점

<ImageBlock
  src="https://media.alchemy.com/1711750158-smart-contract.png"
  alt="스마트 컨트랙트 계정 서명 재사용 취약점"
  width={2400}
  height={1260}
  caption="스마트 컨트랙트 계정 서명 재사용 취약점"
  priority
/>

2023년 10월 27일, Alchemy는 다수의 스마트 컨트랙트 계정\(SCA\)에 영향을 미치는 ERC1271 컨트랙트 서명 재사용\(replay\) 취약점을 발견했으며, 이는 여러 애플리케이션과의 상호작용에서 위험을 초래했습니다. 영향을 받은 SCA에는 Alchemy의 LightAccount와 OKX의 SmartAccount가 포함되었고, 위험이 있는 것으로 파악된 애플리케이션 상호작용으로는 Permit2와 [Cowswap](https://www.alchemy.com/dapps/cowswap)이 있었습니다. 우리는 이 문제를 영향을 받는 여러 SCA 및 애플리케이션에 즉시 알렸으며, 그 과정에서 독립 보안 연구자인 [curiousapple](https://twitter.com/0xcuriousapple)이 한 달 전 동일한 취약점을 이미 발견했다는 사실을 알게 되었습니다. 우리는 curiousapple, [Frangio](https://twitter.com/frangio_)\(ERC1271 저자\), ERC4337 팀, 그리고 다른 SCA 기술 전문가들과 함께 수정 작업을 진행했습니다. 현재 자금이 위험에 처한 상태는 아니며, 애플리케이션에 대한 영향도 상당히 제한적입니다. 관련된 모든 SCA는 위험을 인지했거나 수정 사항을 배포했습니다.

## 기술적 세부사항

### ERC-1271 컨트랙트 서명

Ethereum과 모든 Ethereum Virtual Machine\(EVM\) 기반 체인에는 두 가지 유형의 계정이 있습니다 - 외부 소유 계정\(EOA\)과 스마트 컨트랙트입니다. EOA는 연결된 ECDSA 키 쌍의 개인 키로 서명하여 메시지를 인증할 수 있습니다. 그러나 스마트 컨트랙트는 생성 시 주소가 미리 정해지기 때문에, 메시지 서명에 사용할 개인 키에 쉽게 접근할 수 없습니다.

이 문제를 해결하기 위해 2018년 [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) 컨트랙트 서명 표준이 제안되었습니다. 이 표준을 사용하면 스마트 컨트랙트는 유효한 서명의 조건이 되는 제약/검증 로직을 구현할 수 있고, 애플리케이션은 `contract.isValidSignature`을 호출하여 특정 작업이 해당 스마트 컨트랙트에 의해 승인되었는지 확인할 수 있습니다.

스마트 컨트랙트 계정\(SCA\)의 맥락에서 ERC-1271은 매우 유용한데, SCA 사용자가 EOA와 동일한 방식으로 서명 기반 애플리케이션을 사용할 수 있게 해주기 때문입니다. 이런 애플리케이션에는 [OpenSea](https://www.alchemy.com/dapps/opensea)와 대부분의 DeFi\(토큰 승인 → 호출 UX에 의존하는\)가 포함됩니다.

### ERC1271 서명 재사용 취약점

대부분의 SCA는 위에서 보여준 참조 구현을 사용하여 ERC-1271을 구현합니다. 엔지니어링 관점에서 이는 가벼운 구현이며, `signTypedData`, `signMessage`, `eth\_signTypedData\_v`, `personal\_sign` 같은 메서드를 EOA에서와 동일한 방식으로 재사용할 수 있어 클라이언트 통합이 훨씬 쉬워집니다.

그러나 동일한 주소가 여러 SCA를 소유하고 있고 애플리케이션이 상호작용의 출처 주소를 포함하지 않는 경우, 동일한 서명이 해당 애플리케이션에 대해 두 계정 모두에서 유효하게 됩니다.

이 취약점은 SCA와 애플리케이션의 조합에서만 발생 가능하므로, 이 취약점이 얼마나 심각한지는 이 상호작용이 어떤 애플리케이션과 작동하는지에 달려 있습니다. 우리가 처음 살펴본 애플리케이션은 [Permit2](https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2)였는데, 이는 Uniswap이 구축한 공용 인프라로 업계 전반에 걸쳐 [ERC20](https://www.alchemy.com/overviews/erc20-solidity) 토큰 승인 흐름의 보안과 UX를 개선하며, 오늘날 널리 사용되고 있습니다.

아래 코드 블록은 Permit2 서명이 다루는 구조체를 보여줍니다. 특히, 토큰을 가져오는 주소인 `address owner`는 서명에 포함되지 않으며 대신 Permit2 호출 시 인자로 전달됩니다.

공격자가 이 서명 재사용 취약점을 악용하는 방식은 대략 다음과 같습니다:

1. Bob이 `n`개의 SCA를 소유한 Alice에게 `X` 토큰의 결제를 요청하며, 이를 Permit2를 통해 처리해달라고 요청합니다.
1. Alice가 첫 번째 permit에 서명하면, Bob은 이 permit을 Alice의 모든 SCA에 재사용하여 총 `n X` 토큰을 받을 수 있습니다.

<ImageBlock
  src="https://media.alchemy.com/1711750457-diagram-of-bob-s-attack-on-alice-that-owns-2-scas.png"
  alt="SCA 2개를 보유한 Alice를 대상으로 한 Bob의 공격 다이어그램"
  width={852}
  height={559}
  caption="SCA 2개를 보유한 Alice를 대상으로 한 Bob의 공격 다이어그램"
/>

이 과정에서 우리는 이 취약점을 확인하기 위한 개념 증명\(proof-of-concept\)을 만들었습니다. 여기서 확인할 수 있습니다: [**replay-sig-poc**](https://github.com/omgwiNNING/replay-sig-poc)​

## 영향

조사 과정에서 다음 사실을 확인했습니다:

1. 다수의 SCA가 위험에 노출되어 있었습니다.

1. Alchemy의 LightAccount 외에도, 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), eth-infinitism의 Gnosis Safe용 [EIP4337Fallback](https://github.com/eth-infinitism/account-abstraction/blob/8215b88768d993fb6459c2723d173791a537a2e7/contracts/samples/gnosis/EIP4337Fallback.sol), [AmbireAccount](https://github.com/AmbireTech/wallet/blob/main/contracts/AmbireAccount.sol), OKX의 [SmartAccount](https://github.com/okx/AccountAbstraction/tree/main/contracts/wallet), Argent의 [BaseWallet](https://github.com/argentlabs/argent-contracts/blob/develop/contracts/wallet/BaseWallet.sol), 그리고 [Fuse Wallet](https://github.com/fuseio/fuse-wallet-contracts)이 해당되었습니다.
1. 다수의 애플리케이션이 위험에 노출되어 있었습니다:

1. Permit2 - 서명 기반 전송이 재사용 가능했습니다. 그러나 대부분의 Permit2 사용은 Universal Router를 대상으로 하며, 이를 악용하려면 Universal Router 자체의 별도 심각한 취약점이 필요합니다.
1. Cowswap - ERC-1271 경로를 사용하는 거래가 재사용 가능했습니다. 서명이 `address recipient`를 포함하므로, 여기서의 위험은 최대로 잡아도 오래된 가격 정보 및/또는 일부 MEV 손실 정도입니다.
1. [Gnosis Safe](https://www.alchemy.com/dapps/gnosis-safe)는 이 공격 벡터에 취약하지 않았습니다.

이 시점에서 우리는 텔레그램 그룹을 통해 SCA 및 애플리케이션 측에 이를 공개했으며, curiousapple 역시 한 달 전 동일한 문제를 발견하여 Frangio 및 다른 SCA 기술 전문가들과 수정 작업을 진행 중이었다는 사실을 알게 되었습니다. 지금까지 파악된 영향을 받은 SCA와 애플리케이션 조합의 전체 목록은 아래와 같습니다:

<ImageBlock
  src="https://media.alchemy.com/1711750508-screenshot-2024-02-06-at-1-59-14-pm-1.png"
  alt="ERC-1271 서명 재사용 취약점의 영향을 받는 스마트 컨트랙트 계정 및 애플리케이션 표"
  width={637}
  height={587}
  caption="영향: 계정 및 애플리케이션"
/>

참고: Argent의 경우 모바일 앱이며 기기별로 서명자를 생성하기 때문에, 동일한 EOA가 2개의 SCA를 소유하는 것이 불가능하며, 따라서 서명 재사용 공격이 Argent에는 통하지 않습니다. 다만, Argent의 전체 아키텍처를 포크하지 않고 컨트랙트만 포크한 프로젝트는 위험할 수 있으며, Argent의 지갑 아키텍처를 채택하거나 수정 사항을 배포해야 합니다.

## 수정

위의 재사용 공격을 막기 위해 두 가지 SCA 수정안이 제안되었습니다. SCA 빌더는 이 두 가지 해결책 중 하나를 구현해야 합니다:

두 해결책 모두 ERC-1271 서명 재사용 공격을 막을 수 있습니다. 후자의 해결책이 더 가볍지만, 지갑 클라이언트가 사용자에게 불투명한 해시를 표시해야 한다는 것을 의미합니다. 전자의 수정은 서명이 사용자에게 불투명하지 않도록 보장하기가 더 쉬운 경로이며, 이러한 이유로 우리는 LightAccount에 전자의 수정을 채택했습니다. 대부분의 다른 SCA들도 동일한 수정을 채택했습니다.

## 감사의 말

이 문제에 대해 Howy에게 버그 바운티를 지급해 준 OKX에 깊이 감사드립니다!

Ambire, Instadapp, Biconomy, Cowswap으로부터 버그 바운티를 받은 [curiousapple](https://twitter.com/0xcuriousapple)에게 축하를 전합니다!

추가로, 다음 분들께 큰 감사를 전합니다:

1. 대부분의 SCA가 채택한 EIP-712 구조체 접근 수정안을 함께 고민해 준 [Dror Tirosh](https://twitter.com/drortirosh)
1. ERC-1271에 대한 배경 지식을 공유하고 EIP 위원회를 통해 ERC-1271의 참조 구현 업데이트를 강력히 추진해 준 [Frangio](https://twitter.com/frangio_)
1. 제안된 두 해결책 간의 기술적 구현 차이를 깊이 있게 분석해 준 [Ivo \(Ambire\)](https://twitter.com/ivshti)
1. 중첩된 EIP-712 해결책의 클라이언트 구현에 0.5 ETH 바운티를 걸고 자금을 지원해 준 [Vectorized](https://twitter.com/optimizoor)
1. 위 도전에 응해 [중첩된 EIP712 해결책의 클라이언트 구현](https://github.com/junomonster/nested-eip-712)을 완성하고 Vectorized의 바운티를 획득한 [Juno \(ChainLight\)](https://twitter.com/junorouse)
1. 관련 취약점을 함께 고민하고, 영향을 받은 SCA와 프로토콜을 정리하며, PoC를 제작하는 데 도움을 준 [David Eiber](https://twitter.com/eiber_david)
1. 보안 연구자 및 영향을 받은 다른 SCA와 애플리케이션과의 연결을 포함해 전체 과정에서 도움을 준 [Yoav Weiss](https://twitter.com/yoavw)
