Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-34207 — SSRFフィルターはホスト名のテキストをチェックしていましたが、実際の宛先は後でDNSによって決定されました。そのギャップにより、攻撃者が制御するWebhook URLがループバック、メタデータ、プライベートネットワークのターゲットに到達できました。 | Kitploit
ツール/GitHubGitHub/0xmrma/cve-2026-34207
脆弱性分析エクスプロイトウェブセキュリティペネトレーションテスト論文と研究学習と教育
GitHub0xmrma/cve-2026-34207

CVE-2026-34207

SSRFフィルターはホスト名のテキストをチェックしていましたが、実際の宛先は後でDNSによって決定されました。そのギャップにより、攻撃者が制御するWebhook URLがループバック、メタデータ、プライベートネットワークのターゲットに到達できました。

リポジトリを見る
12ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-34207

SSRFフィルターはホスト名のテキストをチェックしていましたが、実際の接続先は後でDNSによって決定されました。このギャップにより、攻撃者が制御するWebhook URLがループバック、メタデータ、プライベートネットワークのターゲットに到達可能になりました。

はじめに

この問題は、オープンソースのチャットボットビルダーであるTypebotをレビューしているときに、シンプルなセキュリティの問いを念頭に発見しました。

SSRF保護がホスト名のテキストを検証しても、実際の接続先が後でDNSによって決定されたらどうなるか?

この場合、その問いは実際のバグにつながりました。

TypebotのWebhook / HTTPリクエストブロックに対するSSRF保護は、以下しか検証していませんでした:

  • URL文字列、
  • ホスト名リテラルのブロック、
  • リテラルIP形式

リクエストを許可する前にホスト名を解決していませんでした。

つまり、ssrf-repro.exampleのようなホスト名は、検証時には無害に見えても、後で以下のように解決される可能性がありました:

  • 127.0.0.1
  • 169.254.169.254
  • またはRFC1918/プライベートネットワーク空間

そして、バックエンドのHTTPクライアントによってそれでも取得されていました。

この問題はCVE-2026-34207になりました。

Typebot: Typebot on GitHub
CVE: CVE-2026-34207
修正バージョン: 3.16.0

これは、広く使われているオープンソースのチャットボットプラットフォームであるに影響しました。公式サイトでは、Typebotはに信頼されていると紹介されています。また、サイトではとを宣伝しています。

Typebot
世界中の650社以上
月間200万以上のチャット
150万以上の公開ボット
photo0

攻撃チェーン

攻撃者が制御するWebhook URL -> ホスト名がリテラルのみのSSRF検証を通過 -> 許可判断前にDNS解決なし -> バックエンドHTTPクライアントがホスト名を内部ターゲットに解決 -> サーバーサイドリクエストがループバック/メタデータ/プライベートネットワークに到達 -> 実行ログを通じてレスポンスデータが利用可能に


Typebotの機能

Typebotはチャットボットビルダーです。

ユーザーは以下のようなフローを作成できます:

  • 質問をする
  • 構造化された入力を収集する
  • 外部サービスを呼び出す
  • ビジネスロジックを連鎖させる
  • Webhook / HTTPリクエストブロックを通じてアウトバウンドHTTPリクエストをトリガーする

つまり、アウトバウンドリクエストの実行は実際のセキュリティ境界です。

ここでの重要な質問は、TypebotがWebhookブロックをサポートしているかどうかではありませんでした。

本当の質問は:

SSRF保護は、サーバーが実際に接続する接続先を検証しているのか、それともURLに現れるホスト名テキストだけを検証しているのか?

この場合、最初にテキスト形式のみを検証していました。

それが間違いでした。


この攻撃面が注目に値する理由

SSRF防御は非常に予測可能な方法で失敗します。

ほとんどの場合、興味深いミスは次のようなものではありません:

  • 「169.254.169.254をブロックし忘れた」
  • または「localhostをブロックし忘れた」

より深刻なミスは境界のミスです:

  • 正規化の前に検証が行われる
  • リダイレクトの前に検証が行われる
  • DNS解決の前に検証が行われる
  • ある表現で検証が行われるが、ネットワークスタックは別の表現を使用する

ここで注目すべきはまさにその点でした。

Typebotはすでに、リテラルのメタデータIP、ループバック、プライベートレンジ、エンコードされたIPトリックに対するSSRF強化ロジックを持っていました。

そのため、次の質問が明白になりました:

ホスト名自体は危険ではなくても、後で危険な接続先に解決される場合はどうなるか?

それがまさに起こったことです。


根本原因

根本的な問題は、解決されたIPアドレスではなく、ホスト名テキストに基づく接続先検証でした。

脆弱な実装では、validateHttpReqUrl()は:

  • URLを解析
  • http:とhttps:のみ許可
  • metadata.google.internal、metadata.goog、metadata、localhostなどのリテラルホスト名の短いリストをブロック
  • リテラルの10進数/16進数/8進数IPトリックを検出
  • リテラルIPv4/IPv6アドレスを解析
  • ホスト名自体が既にリテラルIPである場合のみアドレスを検証

これが重要な部分です。

ホスト名が通常の値(例:ssrf-repro.example)だった場合、parseIPAddress(hostname)はnullを返し、バリデーターはそこで停止しました。

承認前にDNS解決は行われませんでした。

したがって、脆弱なロジックは実質的に次のようになりました:

root@kitploit:~
const ip = parseIPAddress(hostname);
if (ip) {
  validateIPAddress(ip);
}

つまり:

  • リテラルの危険なIPはブロックされた
  • エンコードされた危険なIPはブロックされた
  • しかし、危険なIPに解決されるホスト名はブロックされなかった

バグの後半は実行パスにありました。

executeHttpRequest()では、Typebotは最初に検証を実行し、その後、ky(request.url, ...)を使用して実際のリクエストを行いました。

したがって、シーケンスは:

  • URL文字列を検証
  • ホスト名を受け入れる
  • 後で実際のアウトバウンドリクエスト中にホスト名を解決
  • 解決された内部ターゲットに接続する

これが脆弱性全体です。


これが単なる不完全なフィルタリングではなく、セキュリティ問題である理由

重要な区別は、信頼の判断がどこで行われたかです。

多くのバグは、悪い説明をすると小さく見えます。

これを次のように説明すると:

「ホスト名フィルターが不完全だった」

品質の問題のように聞こえます。

それが本当の問題ではありません。

本当の問題は:

  • サーバーは実際の接続先を知る前にセキュリティ判断を行った
  • ネットワークスタックは後で別の場所に接続した
  • アプリケーションはそのリクエストを有効として扱った

これは表面的なフィルタリングの弱点ではありません。

これは信頼境界の失敗です。

そして、HTTP実行エンジンが実行ログにレスポンスデータを記録していたため、この問題は最も強いケースでもブラインドではありませんでした。

したがって、これは単なる:

  • 「予期しない内部トラフィックが発生した」

だけではありませんでした。

それは:

  • 内部トラフィックが発生した
  • そして攻撃者はしばしば、通常のアプリケーション動作を通じて証拠とレスポンス内容を回復できた

これは実際のSSRF脆弱性です。


実証コード(PoC)

2つのPoCレイヤーを使用しました。それぞれ異なることを示すためです。

PoC 1:自己完結型ローカルリゾルバーデモ

最初のPoCは根本原因を明確に切り分けました。

小さなローカルハーネスを使用しました:

  • 127.0.0.1でループバックHTTPサーバーを起動
  • http://ssrf-repro.example:18080/...のようなURLを検証
  • 制御されたリゾルバーを使用してssrf-repro.exampleが127.0.0.1に解決されるようにする
  • その後リクエストを実行

これにより、正確な欠陥が実証されました:

  • ホスト名がリテラルのブロック値ではなかったため、検証に合格
  • 後続のリクエストはそれでもループバックに到達

キャプチャされた出力は以下を示しました:

  • バリデータ結果:合格
  • リクエスト実行結果:ループバックに到達
  • ループバックサービスから返されたレスポンスボディ

これにより、検証のギャップが直接証明されました。


PoC 2:実際のTypebot実行パス

2つ目のPoCは、問題のある実際の機能パスを通じてバグを示しました。

最も簡単な再現手順は:

  1. TypebotバックエンドがDNSを解決するマシン上で、無害なホスト名をループバックにマッピングする
  2. ローカルHTTPサービスを起動する
  3. その無害なホスト名を指すWebhookブロックを作成する
  4. 通常の認証済みプレビューまたはライブ実行パスを通じてブロックをトリガーする

代表的なブロックは次のようになります:

root@kitploit:~
{
  "id": "blk-webhook",
  "type": "Webhook",
  "options": {
    "webhook": {
      "method": "GET",
      "url": "http://ssrf-repro.example:8000/"
    }
  }
}

次のようなhostsファイルエントリがある場合:

root@kitploit:~
127.0.0.1 ssrf-repro.example

バリデータは依然としてURLを受け入れました。なぜなら:

  • ssrf-repro.exampleはblockedHostnamesに含まれていなかった
  • localhostではなかった
  • parseIPAddress("ssrf-repro.example")はnullを返した
  • 送信先IPの検証は行われなかった

その後、バックエンドHTTPクライアントはホスト名を127.0.0.1に解決し、接続しました。

これにより、完全な主張が確立されました:

  • 脆弱な検証ロジックは実際の機能使用で到達可能であった
  • リクエストはブロックされたクラスの送信先にヒットした
  • そしてアプリケーションはそれを成功したアウトバウンドHTTPリクエストとして扱った

2つのPoCをこのように選んだ理由

最初のPoCは根本原因を証明します。

2つ目のPoCは製品への影響を証明します。

この分割は重要です。

次のことだけを示しても:

「このフィルターはホスト名を受け入れる」

十分な証明にはなりません。

次のことだけを示しても:

「内部リクエストが発生した」

理由を切り分けていません。

より強力なレポートは:

  • ホスト名ベースの検証が、信頼されるべきではなかった値を受け入れた
  • DNS解決が後にその値の実際のセキュリティ上の意味を変更した
  • バックエンドがブロックされた送信先に接続した
  • そして機能パスが依然として完了した

これが完全なストーリーです。


深刻度と分類

この問題は合理的にHighと分類されました。

アドバイザリの分類は:

  • CWE-918: サーバーサイドリクエストフォージェリ(SSRF)
  • CWE-20: 不適切な入力検証
  • CVSS:
root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L

これは理にかなっています。

これはそれ自体では、認証されていないインターネット全体のSSRFではありませんでした。

必要な権限はLowでした。なぜなら、スタンドアロンのバグでは、Webhook / HTTPリクエストブロックを設定またはトリガーできるアクターが必要だったからです。

しかし、その境界内では、影響は深刻でした:

  • ループバックアクセス
  • プライベートネットワークアクセス
  • メタデータアクセス
  • ログを通じたレスポンスの流出

これ自体が強力なSSRF問題です。

そして、到達可能性を広げる他のバグと組み合わさると、さらに危険になります。


それでも報告する価値があった理由

認証付きSSRFを見ると、すぐに過小評価する人もいます。

それは誤りです。

本当の質問は:

「攻撃者はログインしていたか?」

ではありません。

本当の質問は:

「その攻撃者は、セキュリティモデルが禁止するはずの場所にサーバーを接続させることができたか?」

ここでは、答えはイエスでした。

バリデータは以下を保護すると主張していました:

  • メタデータサービス
  • ループバック
  • RFC1918プライベートレンジ
  • IPv6ローカルレンジ

しかし、ホスト名解決のギャップにより、それら同じ送信先が別の表現を通じて再び侵入可能になりました。

これはまさにCVEに値する種類のバグです。


修正の分析

修正は堅牢でした。症状ではなく、実際の境界を修正したからです。

パッチ適用後の実装では、validateHttpReqUrl()はリクエストを承認する前にホスト名を解決するように変更されました。

バリデータは現在:

  • node:dns/promisesからlookupをインポート
  • 検証を非同期として扱う
  • リテラルでないホスト名を許可する前に解決
  • 解決されたすべてのアドレスを解析
  • 同じブロックレンジに対してすべての解決済みアドレスを検証

これは正しい修正です。なぜなら、信頼判断を以下から変更するからです:

  • 「ホスト名テキストは大丈夫そうか?」

から:

  • 「実際の送信先は許可されたアドレスに解決されるか?」

へと変更します。

これが最初から存在すべきセキュリティ特性です。

また、修正では以下の回帰テストも追加されました:

  • ループバックに解決されるホスト名
  • RFC1918空間に解決されるホスト名
  • セルフホスター向けの許可リスト内部ホスト
  • メタデータおよびループバックターゲットに対するバイパス不可能な保護の維持

これは実際のSSRF修正に求められる強化の種類です:

  • 境界が修正された
  • 意図された動作がコードに文書化された
  • テストによってクラスがロックダウンされた

この問題はTypebot 3.16.0で解決されました。


開示

この問題は、GitHubのセキュリティ報告フローを通じて非公開で報告されました。

報告には以下が含まれていました:

  • validateHttpReqUrl()の根本原因
  • executeHttpRequest()の下流の実行パス
  • ホスト名解決をループバック/プライベートターゲットに使用する現実的な再現戦略
  • 検証のギャップを切り分ける自己完結型デモ

メンテナーは問題を受け入れ、検証ロジックを修正し、脆弱性は後に次のように公開されました:

CVE-2026-34207

修正はTypebot 3.16.0でリリースされました。


このバグが実際に教えること

ここでの重要な教訓はシンプルです:

セキュリティ判断は、ネットワークスタックが実際に使用するのと同じ表現で行われなければならない。

それは明白に聞こえます。

しかし、多くのSSRF保護はまさにそのルールに従わないために失敗します。

  • ホスト名文字列は安全に見える。
  • DNSがその意味を変える。
  • リクエストは依然として送信される。

それだけで十分です。

このバグはまた、SSRFレビュー一般に関する重要なことを強化します:

  • リテラルIPフィルタリングだけでは不十分
  • ホスト名ブラックリストだけでは不十分
  • エンコードIPチェックだけでは不十分

実際の送信先を解決して検証しなければ、SSRFフィルターは依然として不完全です。

それが本当の教訓です。


重要なポイント

  • SSRF防御は、検証が送信先解決の前に行われると失敗する
  • ホスト名テキストの検証は、送信先IPの検証と同じではない
  • Webhook / HTTPリクエスト機能は実際のセキュリティ境界である
  • 認証付きSSRFでも、メタデータや内部サービスに到達する場合は深刻度が高い可能性がある
  • 強力なレポートは根本原因と影響を結びつけるものであり、どちらか一方だけではない
  • 修正は正しかった。なぜなら判断を実際の解決済み送信先に移したからである

最後に

この脆弱性は派手なペイロードに関するものではありませんでした。

適切な境界の問いを問うことに関するものでした。

Typebotでは、SSRFバリデータは最初にホスト名テキストをチェックしました。 実際の送信先は後でDNSによって決定されました。 ネットワーククライアントは解決されたアドレスに従いました。

そのギャップがバグでした。

それがこのissueがCVE-2026-34207になった理由です。

Typebot 3.16.0で修正されました。

ツールをダウンロード