---
title: "ERC-1271署名リプレイ脆弱性"
description: "2023年10月27日、Alchemyは多数のスマートコントラクトアカウント(SCA)に影響を及ぼすERC1271コントラクト署名リプレイ脆弱性を発見した。これにより、複数のアプリケーションとの連携時にリスクが生じていた。"
---

# ERC-1271署名リプレイ脆弱性

<ImageBlock
  src="https://media.alchemy.com/1711750158-smart-contract.png"
  alt="スマートコントラクトアカウントの署名リプレイ脆弱性"
  width={2400}
  height={1260}
  caption="スマートコントラクトアカウントの署名リプレイ脆弱性"
  priority
/>

2023年10月27日、Alchemyは多数のスマートコントラクトアカウント\(SCA\)に影響するERC1271コントラクト署名リプレイの脆弱性を発見し、複数のアプリケーションとのインタラクションにリスクが生じることが分かりました。影響を受けたSCAには当社のLightAccountとOKXのSmartAccountが含まれ、リスクがあると特定したアプリケーションとのインタラクションにはPermit2と[Cowswap](https://www.alchemy.com/dapps/cowswap)が含まれていました。この問題を影響を受ける各SCAおよびアプリケーションに速やかに報告したところ、独立したセキュリティ研究者である[curiousapple](https://twitter.com/0xcuriousapple)が1か月前に同じ脆弱性を発見していたことが判明しました。私たちはcuriousapple、[Frangio](https://twitter.com/frangio_)\(ERC1271の著者\)、ERC4337チーム、および他のSCA技術専門家と協力して修正にあたりました。現時点で資金へのリスクはなく、アプリケーションへの影響もかなり限定的です。関与したすべてのSCAは、リスクを認識するか、修正を出荷済みです。

## 技術詳細

### ERC-1271コントラクト署名

EthereumおよびすべてのEthereum Virtual Machine \(EVM\) 互換チェーンには、Externally Owned Accounts \(EOA\) とSmart Contractsという2種類の異なるアカウントがあります。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を実装しています。エンジニアリング面では軽量な実装であり、EOA向けに使われているのと同じ方法で`signTypedData`、`signMessage`、`eth\_signTypedData\_v`、`personal\_sign`といったメソッドを再利用できるため、クライアント統合がはるかに容易になります。

しかし、同一アドレスが複数の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の署名がカバーするstructを示しています。注目すべきは、トークンの引き出し元アドレスである`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="2つのSCAを所有するAliceに対するBobの攻撃の図"
  width={852}
  height={559}
  caption="2つのSCAを所有するAliceに対するBobの攻撃の図"
/>

この調査の過程で、私たちはこの脆弱性を確認するためのproof-of-conceptを作成しました。こちらから確認できます: [**replay-sig-poc**](https://github.com/omgwiNNING/replay-sig-poc)​

## 影響範囲

調査の一環として、以下のことが判明しました。

1. 複数のSCAがリスクにさらされていた。

1. 当社のLightAccountに加えて、影響を受けた他のSCAには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)はこの攻撃ベクトルに対して脆弱ではなかった。

この時点で、telegramグループを通じてSCAおよびアプリケーションにこの問題を開示したところ、curiousappleも1か月前に同じ問題を発見しており、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はモバイルアプリであり、署名者をデバイスごとに生成するため、2つのSCAが同一のEOAによって所有されることはあり得ず、したがって署名リプレイ攻撃はArgentに対して機能しません。ただし、Argentのアーキテクチャ全体をフォークせずにそのコントラクトのみをフォークしたプロジェクトはリスクにさらされる可能性があり、Argentのウォレットアーキテクチャを採用するか、修正を出荷する必要があります。

## 修正

提案されたSCAの修正は2つあります。SCAビルダーは、上記のリプレイ攻撃を防ぐためにこの2つの解決策のいずれかを実装すべきです。

どちらの解決策もERC-1271署名リプレイ攻撃を防ぐことができます。後者の解決策はより軽量ですが、ウォレットクライアントはユーザーが署名するために不透明なハッシュを表示しなければならなくなります。前者の修正は、署名がユーザーにとって不透明にならないようにする上でより容易な方法であり、そのためLightAccountについては前者の修正を採用しました。他のほとんどのSCAも同じ修正を採用しています。

## 謝辞

この問題についてHowyにバグバウンティを支払ってくれたOKXに大変感謝します!

Ambire、Instadapp、Biconomy、Cowswapからバグバウンティを受け取った[curiousapple](https://twitter.com/0xcuriousapple)、おめでとうございます!

さらに、以下の方々にも大きな感謝を:

1. 多くのSCAが採用したEIP-712 struct方式の修正案をブレインストーミングしてくれた[Dror Tirosh](https://twitter.com/drortirosh)
1. ERC-1271に関する背景をさらに共有してくれ、EIP委員会を通じてERC-1271のリファレンス実装を更新するために大きく尽力してくれた[Frangio](https://twitter.com/frangio_)
1. 提案された2つの解決策の技術的な実装の違いを深く掘り下げてくれた[Ivo \(Ambire\)](https://twitter.com/ivshti)
1. nested EIP-712解決策のクライアント実装に対して0.5 ETHのバウンティを立て、資金提供してくれた[Vectorized](https://twitter.com/optimizoor)
1. その課題に挑み、[nested 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)
