脆弱性は設計時に潰す!生成AIによるシーケンス図レビュー自動化の実践テクニック
この記事は、以前公開した「Geminiで要件・設計のセキュリティレビューを自動化し、工数を90%削減した話」という記事を補完する、より実践的な内容です。
前回の記事では、要件定義や基本設計といった上流工程のドキュメントを包括的にレビューするアプローチを紹介しました。今回は 「シーケンス図」 に特化し、具体的なプロンプトでセキュリティリスクを発見する手法を深掘りします。(前回の記事は未読でも問題ありません)
はじめに
マイクロサービス化やSaaSの利用が当たり前になった今、私たちのシステムは多くの外部システムと連携して動作しています。
GA technologies が運営する AI不動産投資「RENOSY(リノシー)」 のシステムも、契約や決済などビジネスインパクトの大きな手続きも含め、様々な外部システムを自社のシステムと統合することで実現しています。
- 不動産売買契約の締結に電子署名SaaSを利用
- 手付金の支払いに決済代行サービスを利用
- 自社の認証基盤を外部システムに連携
これらの連携は非常に強力ですが、その システム間の「つなぎ目」 には、見過ごされがちなセキュリティリスクが潜んでいます。この「つなぎ目」に潜むリスクを、開発の早い段階で特定する有効な手法の一つが 「シーケンス図レビュー」 です。そこでこの記事では、シーケンス図レビューの具体的な手順と、そのプロセスを生成AIでいかに効率化したかを紹介します。
対象読者
この記事は、特に以下のような課題を感じている方々に向けて書いています。
- 設計段階のセキュリティレビューに課題を感じている開発者・セキュリティ担当者の方
- セキュリティのシフトレフトを推進したいエンジニアリングマネージャーの方
- 生成AIを活用した具体的な業務改善事例に興味がある方
シーケンス図の何に注目すべきか
一般的なWebアプリケーションでは、通信経路は次の3つに分けられます。
- ① ブラウザ ⇒ 自社システム
- ② ブラウザ ⇒ 外部システム
- ③ 自社システム ⇔ 外部システム
私たちのシーケンス図レビューでは、 ①の「ブラウザ ⇒ 自社システム」間の通信に注目 します。なぜなら、
- ②は外部システムのセキュリティ責務であり、私たちが直接コントロールできる範囲外。
- ③はサーバー間通信であり、APIキーやIPアドレス制限といった確立された方式で認証を行うことを原則としているため、個別のシーケンス図レビューの主眼からは外します。
したがって、レビューの目的は 「ユーザー操作に起因するアプリケーションレイヤーの脅威」 を洗い出すことになります。
注釈: 私たちのプロダクトはWebアプリケーションが主であるためこの観点でレビューしていますが、サーバー間通信が中心となるシステムの場合はまた別の観点が必要になるでしょう。
ブラウザからの通信に潜む5つの脅威
「ブラウザ ⇒ 自社システム」の通信では、特に以下の脅威を想定してレビューを行います。
- 改ざん:送信されるデータ(ID、金額、ステータスなど)が書き換えられる。これにより、他人の情報にアクセスされたり(IDOR: Insecure Direct Object Reference)、本来許可されていない操作が実行されたりする。
- 迂回:本来経由すべき処理(確認画面などや有効・無効のチェック)をスキップされる
- 再送: 一度成功したリクエストをコピーして何度も送られる
- 遅延 (ToCToU): 確認と使用のタイミングの差を悪用される
- 同時実行: 複数のリクエストを同時に送り、チェックをすり抜ける
注釈: シーケンスレビューでは他の脅威(例えば「なりすまし」「権限昇格」「サービス拒否」など)を発見することもできます。プロダクトの性質や他のレビュー・テストによるカバレッジに合わせて効率よく実施しましょう!
脅威例①:改ざん (Tampering)
外部サービスからのコールバックURLに含まれるパラメータをユーザーが改ざんし、システムのステータスを不正に操作する攻撃。
- もし... このコールバックURLのstatusパラメータをユーザーがfailedからsuccessに書き換えたら?
- 対策: コールバックURLのパラメータを信用せず、サーバー間で直接APIを呼び出して契約ステータスを再確認する。または、コールバックに電子署名を付与し、改ざんを検知する。
脅威例②:再送 (Replay Attack)
某ギフト券を付与するリクエストを攻撃者がコピーし、何度もサーバーに送りつけることで、ギフト券を無限に取得する攻撃。
- もし... この正常なリクエストをコピーされ、何度も再実行されたら?
- 対策: リクエストごとに一度しか使えないトークン(nonce)を発行し、サーバー側で検証する。
脅威例③:迂回・遅延・同時実行
一つのクーポン利用シーケンスに、複数の脅威が潜んでいます。
この一連の流れの中に、以下のような攻撃のリスクが考えられます。
- 迂回 (Detour):
- もし... /check_coupon を経由せずに、直接 /purchase リクエストを送られたら?
- 対策: 購入確定時に、有効性チェックをパスしたことを示すトークンなどを検証する。例えば、/check_coupon のAPIレスポンスで一度しか使えないトークン(ワンタイムトークン)を発行し、/purchase のリクエスト時にそのトークンを必須パラメータとすることで、チェック処理を必ず経由させることができます。
- 遅延 (ToCToU - Delay):
- もし... /check_coupon でOKが出た後、クーポン期限が切れるまでリクエストを遅延させ、期限切れの /purchase リクエストを送られたら?
- 対策: 購入確定時(Useの直前)に、再度クーポンの有効性(期限など)をチェックする。
- 同時実行 (Race Condition):
- もし... /check_coupon でOKが出た後、/purchase リクエストをほぼ同時に複数送られたら?
- 対策: クーポンを使用済みに更新する処理をアトミックに行い(DBロックなど)、二重使用を防ぐ。
人力によるセキュリティレビューの限界と、生成AIによる解決
上記のレビューを人力でやるには、属人化・抜け漏れ・工数の問題がありました。そこで私たちは、これらのレビューを生成AIで分析できないか検証しました。
ここではRENOSYにおける不動産売買契約の電子契約手続きシーケンス(を脆弱に改悪した版)をGeminiに分析させた例を紹介します。
セキュリティレビューのプロンプト例
私たちは生成AIにシーケンス図レビューを実行させるために、次のようなプロンプトを作成しました。ポイントは、シーケンス図をテキスト形式(MermaidやPlantUMLなど)で渡し、レビューに必要なコンテキストを併せて与えることです。
【役割設定】
あなたは、Webアプリケーション開発におけるセキュリティの脅威と対策に精通した、経験豊富なセキュリティエンジニアです。
【自社システムの名称と概要】
- RENOSY:不動産投資をする顧客向けのサービス。物件のオーナー向けにマイページを提供している。
【前提条件】
- シーケンスが実行される前に、ユーザーはID/パスワード等で認証されている
- すべての通信はHTTPSで、通信相手の認証と、メッセージの機密性と完全性は保証されている
【具体的な手順】
以下の手順で、提供されたシーケンス図を分析してください。
- シーケンス図内の通信を「①ブラウザ⇒自社システム」「②ブラウザ⇒外部システム」「③自社システム⇔外部システム」の3つに分類します。
- 分析対象は「①ブラウザ⇒自社システム」の通信のみとします。
- この通信に対して、「改ざん」「迂回」「再送」「遅延(ToCToU)」「同時実行(レース)」の脅威がないか分析してください。
- 分析結果は、脅威が潜む通信の箇所(番号)、具体的な指摘事項、対策例を箇条書きで出力してください。
【シーケンス図】
%% このシーケンス図には解説のための意図的な脆弱性が含まれています。この設計をそのまま再利用しないでください。
sequenceDiagram
autonumber
actor ユーザー
participant ブラウザ
participant RENOSY
participant 電子契約SaaS
ユーザー->>ブラウザ: 契約(ID=123)の開始ボタンを押す
ブラウザ->>RENOSY: POST /mypage/contracts/123/start
RENOSY->>電子契約SaaS: POST /contracts/create
電子契約SaaS->>電子契約SaaS: OneTimeToken(otp) を発行
RENOSY-->>ユーザー: 契約画面リンクのメールを送信
電子契約SaaS-->>RENOSY: 200 OK : 契約書IDは9876
RENOSY->>RENOSY: 契約ID 123 と 契約書ID 9876を紐づけ
RENOSY-->>ブラウザ: 200 OK
ブラウザ->>ユーザー: 「メールを確認してください」と表示
ユーザー->>ブラウザ: メールリンクを開く
ブラウザ->>電子契約SaaS: GET /contracts/9876?otp=hogehoge
電子契約SaaS->>電子契約SaaS: otpを認証
電子契約SaaS-->>ブラウザ: 200 OK 契約書面 + 署名欄
ブラウザ->>ユーザー: 契約書面 + 署名欄を表示
ユーザー->>ユーザー: 契約内容をよく読む
ユーザー->>ブラウザ: 署名
ブラウザ->>電子契約SaaS: POST /contracts/9876/complete
電子契約SaaS->>電子契約SaaS: 契約完了
電子契約SaaS-->>ブラウザ: redirect to /mypage/contracts/123/callback?status=ok
ブラウザ->>RENOSY: GET /mypage/contracts/123/callback?status=ok
RENOSY->>RENOSY: 契約ID 123を完了
RENOSY-->>ブラウザ: 200 OK
ブラウザ->>ユーザー: 「契約が完了しました」と表示
※注:このシーケンス図には解説のための意図的な脆弱性が含まれています。自信のある人は自力で脆弱性を探してみてください。こんな図です↓
生成AIによる分析結果(Gemini 2.5 Proの出力そのまま)
分析対象となる「①ブラウザ⇒自社システム」の通信は以下の2つです。
- 2: POST /mypage/contracts/123/start
- 20: GET /mypage/contracts/123/callback?status=ok
これらの通信について、脅威が潜む可能性のある箇所、具体的な指摘事項、対策例を以下に示します。
通信箇所: 2 POST /mypage/contracts/123/start
- 脅威: 改ざん (IDOR - Insecure Direct Object Reference)
- 具体的な指摘事項:
URLに含まれる契約ID (123) を攻撃者が別のIDに書き換えてリクエストした場合、サーバー側でそのIDの所有者確認(認可)を行っていないと、他人の契約を開始できてしまう脆弱性(IDOR)が存在する可能性があります。 - 対策例:
リクエストを処理する際に、現在認証されているユーザーのセッション情報と、リクエストされた契約IDを紐付けて検証し、本人の契約であることを必ず確認してください。
- 具体的な指摘事項:
- 脅威: 再送 / 同時実行 (レースコンディション)
- 具体的な指摘事項:
ユーザーが意図的(攻撃)または非意図的(ブラウザのダブルクリックなど)にリクエストを短時間に連続して送信した場合、同一の契約に対する開始処理が複数回実行されてしまう可能性があります。これにより、電子契約SaaS側に意図せず複数の契約が作成されたり、ユーザーに同じ契約案内メールが複数通送信されたりする恐れがあります。 - 対策例:
- フロントエンドでの対策: 契約開始ボタンを一度クリックしたら、処理が完了するまでボタンを非活性化(disabled)します。
- バックエンドでの対策(冪等性の確保):
- 契約に「未処理」「処理中」「処理済み」などのステータスを持たせ、「未処理」の場合のみ契約開始処理を受け付けるようにします。
- リクエストごとにユニークなトークン(トランザクショントークン)を発行し、一度処理したトークンを持つリクエストは受け付けないようにします。
- 具体的な指摘事項:
- 脅威: 遅延 (ToCToU - Time-of-Check to Time-of-Use)
- 具体的な指摘事項:
ユーザーが契約開始ボタンを押した時点(Time-of-Check)と、サーバーが実際に処理を開始する時点(Time-of-Use)の間に時間差があります。この間に、契約の前提条件(例: 対象物件が購入可能であること)が変化する可能性があります。チェック時と使用時で状態が異なっていると、本来開始できないはずの契約プロセスが進行してしまう恐れがあります。 - 対策例:
契約開始処理のトランザクション内で、あらためて契約のステータスや前提条件を再検証してください。
- 具体的な指摘事項:
通信箇所: 20 GET /mypage/contracts/123/callback?status=ok
- 脅威: 改ざん
- 具体的な指摘事項:
このリクエストは電子契約SaaSからのリダイレクトを起点としますが、実行主体はユーザーのブラウザです。そのため、URLのパラメータは容易に改ざん可能です。- 契約IDの改ざん (IDOR): 契約ID (123) を他人のIDに書き換えることで、他人の契約ステータスを不正に「完了」にできてしまう可能性があります。
- ステータスの偽装: クエリパラメータの status=ok は信頼できません。攻撃者は、実際には電子契約SaaS上で契約が完了していなくても、このURLを直接実行することで、貴社システム内のステータスだけを「完了」にできてしまう可能性があります。
- 対策例:
- (IDOR対策): POST /mypage/contracts/123/start と同様に、認証済みユーザーと契約IDの所有者確認を必ず行ってください。
- (ステータス偽装対策): このコールバックを「処理開始のトリガー」とのみ位置づけ、ステータスの正当性を担保するために、以下のいずれか、または両方の対策を実施してください。
- 【推奨】サーバー間でのステータス検証: コールバックを受けたら、RENOSYのサーバーから電子契約SaaSのAPI(例: 契約ステータス確認API)を直接呼び出し、対象の契約書ID(9876)のステータスが本当に「完了」しているかを検証します。このサーバー間通信の結果をもって、初めて自社システムのステータスを更新してください。
- リクエスト署名の検証: 電子契約SaaSが対応している場合、コールバックURLに含めるパラメータに署名(例: HMAC)を付与してもらい、貴社システム側でその署名を検証することで改ざんを検知します。
- 具体的な指摘事項:
- 脅威: 迂回 / 再送
- 具体的な指摘事項:
このコールバックURLを知っていれば、誰でも(あるいは本人が何度も)リクエストを送信できます。- (迂回): 認証・認可のチェックがなければ、電子契約SaaSでのプロセスを完全に迂回して契約を完了したかのように見せかけることが可能です。
- (再送): 完了処理に冪等性がない場合、リロードなどによってリクエストが再送されるたびに完了処理が実行されてしまいます。例えば、契約完了時にインセンティブ(ポイント付与など)を付与するロジックがあれば、それが複数回実行されてしまいます。
- 対策例:
- (迂回対策): このエンドポイントにも、他のマイページ内APIと同様に、必ず認証・認可のチェックを実装してください。
- (再送対策): 契約ステータスを厳密に管理し、一度「完了」ステータスになった契約に対しては、再度完了処理が実行されないように冪等性(何度実行しても結果が同じであること)を確保してください。
- 具体的な指摘事項:
考察
上記の分析結果から、レビューに生成AIを活用することで、 他人の契約を開始できてしまう(IDOR)、あるいは 契約が完了していないにも関わらず完了済みとして扱われてしまう(ステータス偽装) といった、ビジネスインパクトの大きいリスクを設計段階で発見し、未然に防げる可能性が示されました。
AIが全ての仕事をしてくれるわけではありませんが、AIに一次レビューを任せることで、人間はより創造的で高度な判断に集中できるようになります。
- AIの役割(機械的な作業)
- 定義された観点に基づく、抜け漏れのない網羅的なチェック
- 典型的な脆弱性パターンの洗い出し
- 人間の役割(創造的な判断)
- ビジネス影響度やユーザー体験を考慮したリスクの評価
- AIでは検知が難しい、ドメイン固有の仕様に潜む脅威の分析
- 最終的な仕様の決定と、対策の妥当性の判断
まとめ
- シフトレフトを実現する上で、設計段階でのセキュリティレビューは非常に重要です。
- 外部システムとの連携部分に潜むリスクを発見するには、シーケンス図レビューが有効な手法です。
- 一次レビューをAIに任せることで、再現性のある結果を迅速に得ることができ、開発プロセス全体の効率化につながります。
Discussion