
Cobo DeFi セキュリティ講座(下):DeFiにまつわるよくあるセキュリティ脆弱性とその予防策
TechFlow厳選深潮セレクト

Cobo DeFi セキュリティ講座(下):DeFiにまつわるよくあるセキュリティ脆弱性とその予防策
過去1年以上にわたりWeb3業界で発生した重大なセキュリティインシデントの原因分析と回避策
著者:Max Cobo セキュリティディレクター
本稿はCobo Globalの第24記事目です。
Moledaoの招待を受け、CoboのセキュリティディレクターMaxは最近オンラインでコミュニティメンバー向けにDeFiセキュリティ講座を実施しました。Maxはここ1年余りのWeb3業界における重大なセキュリティインシデントを振り返り、それらの原因と回避方法について重点的に議論しました。一般的なスマートコントラクトのセキュリティ脆弱性と予防策をまとめ、プロジェクトチームや一般ユーザーに対していくつかのセキュリティアドバイスも提供しています。ここではMaxの講義内容を前編・後編の二部構成で公開し、DeFi愛好家の皆様が収集・保存できるようにいたします。
前編:『Cobo DeFiセキュリティ講座(前編):2022年DeFiセキュリティ大事件の総括』
一般的なDeFiの脆弱性には、フラッシュローン、価格操作、関数権限問題、任意外部呼び出し、fallback関数の問題、ビジネスロジックのバグ、秘密鍵漏洩、リエントランシー攻撃などがあります。

2022年11〜12月のセキュリティインシデント統計
特に注目すべきは、フラッシュローン、価格操作、リエントランシー攻撃の3種類です。
フラッシュローン
-
一般的な攻撃手法としてフラッシュローンが頻繁に利用される。攻撃者は大量の資金を借り入れて価格操作や業務ロジックの改ざんを行う;
-
開発者は、自社のコントラクト機能が巨額の資金により異常をきたす可能性、あるいは一連の取引の中で複数の関数とやり取りして報酬を得るケースなどを考慮しなければならない;
-
多くのコントラクトではトークン数量が報酬計算やDEXペアの数量計算に使用されているが、開発者がこれらの変数がフラッシュローンによって操作可能であることを想定していないため、結果としてコントラクトの資金が盗まれる事態に至っている。
フラッシュローン自体はDeFiにおけるイノベーションだが、悪意ある攻撃者にとってはコストゼロで資金を借りられる手段となる。彼らは資金を借り、裁定取引プロセスを完了した後に返済し、残った利益を得ることができる。ガス代だけ支払えば、巨額の利益を得られるのである。
過去2年間で、フラッシュローンを利用した多数の問題が発生している。多くのDeFiプロジェクトは表面的には高いリターンを謳っているが、実際の運営者の技術レベルはまちまちだ。コードを購入したものもあり、コード自体にバグがなくてもロジック上に問題があることがある。例えば、特定のタイミングで保有者のトークン保有量に基づいて報酬を配布する仕組みが、攻撃者によってフラッシュローンで大量のトークンを購入され、報酬の大半を奪われるというケースがある。また、トークン価格を計算する際にフラッシュローンで価格を操作できるプロジェクトもある。こうした点について、プロジェクト側は十分に警戒すべきである。
価格操作
価格操作問題はフラッシュローンと密接に関係しており、主に価格計算時にユーザが制御可能なパラメータを使用していることに起因する。典型的な問題は以下の2つがある。
-
第三者のデータを使用するが、使用方法が誤っていたり検証が不十分なために価格が悪意を持って操作される。
-
あるアドレスのトークン残高を計算変数として使う場合、その残高を一時的に増減できてしまうことが問題となる。
リエントランシー攻撃
外部コントラクトを呼び出す際の主なリスクの一つは、制御フローを乗っ取られ、予期しない関数呼び出しによってデータが改ざんされる可能性があることだ。
```
mapping (address => uint) private userBalances; function withdrawBalance() public {
uint amountToWithdraw = userBalances[msg.sender];
(bool success, ) = msg.sender.call.value(amountToWithdraw)(""); // msg.senderがコントラクトの場合、そのfallbackコードが実行され、withdrawBalanceを再び呼び出してリエントランシー攻撃が可能になる
require(success);
userBalances[msg.sender] = 0;
}
```
ユーザーの残高が関数の最後までゼロにならないため、2回目以降の呼び出しでも成功し、残高を繰り返し引き出せる。
異なるコントラクトにおいて、リエントランシーはさまざまな形で存在する。単一関数だけでなく、複数の関数や複数のコントラクトを組み合わせた攻撃も可能であるため、以下の点に注意が必要である:
1. 単一関数のリエントランシー防止だけでなく、全体的な設計を考慮すること;
2. Checks-Effects-Interactionsパターンに従ってコーディングすること;
3. 時間をかけて検証されたリエントランシー防止用modifierを使用すること。
最も恐ろしいのは「車輪の再発明」であり、すべてを自分で作ろうとすることだ。この分野には既に確立されたセキュリティベストプラクティスが多数存在する。それらを活用すればよく、わざわざ再開発する必要はない。独自の仕組みを作成しても、十分な検証が行われていないため、成熟した既存のソリューションよりも問題が発生する確率が遥かに高くなる。
Omni Protocolはリエントランシーの問題によりハッキングされ、もう一つの物語がある:
Omni Protocol脆弱性の裏にある物語 ― 4人のハッカーの対決
イーサリアムのmempoolは常に多数のハッカーによって監視されており、取引を分析して利益が出そうなものを先んじて実行することで利益を得ている。Omni Protocolの脆弱性を発見した人物が提出した攻撃トランザクションは、2人のハッカーに捕捉され、彼らはフラッシュボットを使って先に実行することで、Omni Protocolから1200ETHを奪い取った。一方、脆弱性を発見した攻撃者はわずか480ETHしか得られなかった。さらに別のハッカーが、この「先取りハッカー」がフラッシュボットに提出した攻撃トランザクションに気づき、Doodle ERC20トークンの購入が必要な点に着目してサンドイッチアタックを行い、151ETHを獲得した。
脆弱性を発見した者が最大の利益を得るわけではない。むしろ「暗黒の森」に潜む他の狩人の方が大きな利益を得ることが多い。このエコシステムにはあらゆる場所に狩人がいる。狩人は互いに獲物にもなりうる。たとえ攻撃の開始者であっても、新人であればプロジェクトの大部分の資金を持ち去るのは難しい。一度にすべてを奪わない限り、多くの人々がより高いガス代を払って先に取引を実行しようとする。また、DEXでのトークン売買が絡めば、サンドイッチアタックのリスクもあり、非常に混沌とした状況になる。
セキュリティアドバイス
最後に、プロジェクトチームと一般ユーザーへのセキュリティアドバイスを紹介する。
プロジェクトチーム向けセキュリティTips
1. コントラクト開発ではベストセキュリティプラクティスを遵守する。
2. コントラクトはアップグレード可能・一時停止可能であること:多くの攻撃は一気にすべての資金を移動するのではなく、複数の取引で段階的に行われる。適切なモニタリング体制があれば早期発見でき、コントラクトを一時停止できる仕組みがあれば損失を最小限に抑えることができる。
3. タイムロックの導入:Ankrの事例のようにタイムロックがあれば、たとえば48時間後にのみ実行可能にする。この期間中に、誰もが mint 権限が再設定され、誰でも使えるようになったことに気づき、プロジェクトがハッキングされたと判断できる。監視者はプロジェクトチームに通知できるし、仮に無視されても、少なくとも自分の資産は先に引き出すことで保護できる。つまり、タイムロックがないプロジェクトは理論的にリスクが高まる。
4. セキュリティ投資を強化し、包括的なセキュリティ体制を構築する:セキュリティは一点の問題でもなく、一本の線でもない。体系的なものである。プロジェクトチームだからといって、複数の企業による監査を受けていれば安全だと考えるべきではない。北朝鮮のハッカーが秘密鍵を盗んでしまうかもしれない。マルチシグであっても、すべての秘密鍵を盗まれることはある。また経済モデルやビジネスモデルに問題があれば… 資金損失につながる要因は無数にあり、事前にリスクをどれだけ回避できるかが重要だ。リスクモデリングを行い、可能な限り多くのリスクを排除し、残るリスクは許容範囲内に抑えるべきである。セキュリティと効率の両立は不可能なので、ある程度の妥協が必要だ。しかし、まったくセキュリティに投資しないなら、攻撃されるのは当然のことである。
5. 全従業員のセキュリティ意識を高める:セキュリティ意識の向上には高度な技術は不要である。TwitterではよくフィッシングでNFTを失う人がいるが、これは人間の心理的弱点を突いたものだ。少し注意すれば回避できる。Web3の環境では、「なぜ?」と少し多く問いかけるだけで、多くの問題を未然に防げる。
6. 内部犯行を防ぎ、効率化と同時にリスク管理を強化する:再びAnkrの例を挙げよう。第一に、コントラクトのOwnerがシングルサインでなくマルチシグであること。秘密鍵を失えばプロジェクト全体が乗っ取られる。第二に、タイムロックがなく、重要な更新が即時反映され、誰も気づかないまま不公平な状態になる。第三に、内部の管理体制がまったく機能していない。
ブロックチェーン上のプロトコルは、効率性を保ちながら安全性を高めるにはどうすればよいか?ここで宣伝になりますが、Cobo Safeをおすすめします。マルチシグを採用すれば、若干の効率低下は避けられない。しかしCobo Safeを使えば、5つの署名者のうち3人が承認するといった設定が可能になる。また、信頼できるノードにセキュリティ監視を任せ、攻撃を検知した際に一時停止機能を実行させることもできる。
たとえばDEXのマーケットメーカーの場合、Owner権限を制限しないと、Ownerが資金を別のアドレスに送金できてしまう。Cobo Safeを使えば、送金先アドレスや操作可能な通貨ペアを限定し、資金の引き出し先も特定のアドレスに制限できる。Cobo Safeは効率性を維持しつつ、一定のセキュリティを確保できる。
7. サードパーティの安全性を慎重に評価する:エコシステムの一環として、プロジェクトには必ず上流・下流が存在する。「上流・下流はすべて安全ではない」という原則を守るべきである。上流・下流の両方に対して検証を行う必要がある。サードパーティは制御不能であり、セキュリティリスクが非常に大きいため、導入には細心の注意を払うべきだ。コントラクトがオープンソースであれば、それを読み込んで利用できる。しかし非公開であれば、絶対に参照してはいけない。中身のロジックが分からないし、もしそのコントラクトがアップグレード可能だった場合、普段は問題なくても、突然悪意のあるコントラクトにアップデートされる可能性があり、それは制御不能である。
ユーザー/LPがスマートコントラクトの安全性を判断する方法
一般ユーザーがプロジェクトの安全性を判断するには、以下の6点を確認すべきである:
1. コントラクトがオープンソースかどうか:コントラクトが非公開のプロジェクトには絶対に手を出さないこと。中身が何なのか全く分からないからである。
2. Ownerがマルチシグを採用しているか、マルチシグが分散化されているか:マルチシグでなければ、セキュリティインシデント発生時にそれがハッカーによるものか判断できない。マルチシグであっても、それが本当に分散化されているかを確認する必要がある。
3. コントラクトの取引履歴:特に市場にはフィッシング詐欺プロジェクトが多く、似たようなコントラクトを作ることがある。そのため、コントラクトのデプロイ時期やインタラクション回数などを確認し、安全性の判断材料とすべきである。
4. コントラクトがプロキシコントラクトか、アップグレード可能か、タイムロックがあるか:完全にアップグレードできないコントラクトは硬直的すぎる。アップグレード可能であることが望ましい。ただしアップグレードには方法が必要で、重要なパラメータ変更時にはタイムロックを設け、ユーザーに判断の猶予を与えるべきである。これは透明性の一種でもある。
5. 複数の機関による監査を受けているか(監査会社を盲信しない)、Owner権限が大きすぎないか:一つの監査会社だけを信用してはならない。異なる監査会社や担当者は異なる視点を持つため、複数の監査で異なる問題が指摘され、修正されているプロジェクトの方が、単一監査より安全である。責任あるプロジェクトチームは複数の監査機関によるクロスチェックを行う。
また、Ownerの権限が大きすぎないかも確認する。例えば一部の貔貅盤(ピシャオパン)プロジェクトでは、Ownerがユーザーの資金を完全に制御できる。少量なら正常に取引できるが、大量に購入すると即座にロックされ取引不能になる。NFTプロジェクトでも同様だ。健全なプロジェクトではOwnerの権限は制限され、危険な操作はできない。重要な操作はタイムロック付きで、ユーザーが内容を確認できるようにすべきである。特に相場が悪い時期には、逃亡プロジェクトが多発するため、Ownerの権限には特に注意が必要だ。
6. オラクルに注意:プロジェクトが主流のオラクルを利用しているなら、大きな問題はない。しかし独自のオラクルや、誰でも簡単に担保としてトークンを預けて価格情報を提供できるようなオラクルを使用している場合は注意が必要だ。オラクルに問題がある、あるいは操作可能だと判明した時点で、たとえリターンが高くても参加すべきではない。
TechFlow公式コミュニティへようこそ
Telegram購読グループ:https://t.me/TechFlowDaily
Twitter公式アカウント:https://x.com/TechFlowPost
Twitter英語アカウント:https://x.com/BlockFlow_News













