Modern Frontend CVEs

対象CVE: GHSA-xg5g-26x8-cvf4

[解説] BudibaseのSSRF脆弱性:Node.jsアプリケーションにおけるDNSリバインディングの脅威とフロントエンドへの影響

ローコード開発ツールBudibaseで発覚した、DNSリバインディングを悪用した深刻なSSRF脆弱性について、Node.jsアプリケーションの文脈から技術的に解説。フロントエンド開発者も知っておくべき内部システムへの不正アクセス手法と、自身の開発環境への影響、そして対策を深掘りします。

はじめに:なぜフロントエンドエンジニアがSSRFに注目すべきか?

皆さんは普段、Webアプリケーションの「顔」となるUI/UXを構築するフロントエンドエンジニアとして、APIを「利用する側」にいることが多いでしょう。そのため、サーバーサイド・リクエスト・フォージェリ(SSRF)と聞くと、バックエンドの脆弱性というイメージが強いかもしれません。

しかし、Node.jsベースのビルドツールや開発サーバー、あるいはサーバーサイドレンダリング(SSR)やAPI Routesを持つフレームワーク(Next.jsなど)が普及した現代において、フロントエンド開発者もまた、内部的にネットワークリクエストを発行するコードを扱う機会が増えています。今回解説するBudibaseの脆弱性は、まさにNode.jsアプリケーションで発生したSSRFであり、DNSリバインディングという巧妙な手口が使われています。直接Budibaseを利用していなくても、この攻撃手法は皆さんの開発環境やCI/CDパイプラインにも潜在的な影響を及ぼす可能性があるため、ぜひご一読ください。

GHSA-xg5g-26x8-cvf4の概要:Budibaseに見つかった深刻な脆弱性

今回取り上げる脆弱性(GHSA-xg5g-26x8-cvf4)は、オープンソースのローコード開発プラットフォームであるBudibaseで発見されました。深刻度は「High」と評価されています。

この脆弱性は、Budibaseの「OpenAPIインポート機能」および「RESTクエリ実行機能」に存在します。認証済みの(Budibaseのビルダー権限を持つ)ユーザーが悪用することで、本来アクセスできないはずのBudibaseサーバー自身や、そのサーバーが稼働しているプライベートネットワーク内部のHTTPサービスに対して、任意のHTTPリクエストを発行させることが可能になります。これはまさにSSRF攻撃であり、攻撃者はこの手口を使って内部システムから情報を窃取したり、不正な操作を実行したりする可能性があります。

DNSリバインディング攻撃のメカニズムを理解する

SSRF攻撃の中でも特に巧妙な手口の一つが「DNSリバインディング」です。これは、DNS(Domain Name System)の名前解決の仕組みを悪用し、セキュリティ対策をすり抜ける攻撃です。

攻撃の流れは以下のようになります。

1. **ステージ1:セキュリティ検証時**<br>攻撃者は、自身が管理するドメイン名(例: <code>evil.example.com</code>)を用意します。このドメインのDNSレコードを操作し、最初の名前解決時には、インターネット上に公開されている安全な外部IPアドレスを返します。Budibaseのようなアプリケーションは、この時点でURLのホスト名を解決し、それがプライベートIPアドレスではないことを確認して「安全」と判断します。

2. **ステージ2:実際の通信時**<br>数秒後、またはシステムが実際にHTTPリクエストを送信するタイミングで、攻撃者はDNSレコードを素早く変更します。今度は<code>evil.example.com</code>の名前解決に対して、サーバーのプライベートIPアドレス(例: <code>127.0.0.1</code>や内部ネットワークのIP)を返します。この際、DNSのTTL(Time To Live)を非常に短く設定することで、DNSキャッシュがすぐに期限切れとなり、新しいIPアドレスが取得されるように仕向けます。

これにより、アプリケーションは「安全だと検証したはずのホスト名」で、実際には内部ネットワークのサービスに対してリクエストを送ってしまうのです。フロントエンド開発者が<code>localhost</code>をターゲットとする開発サーバーを動かしている場合などにも、このDNSリバインディング攻撃が利用されるケースがあるため、身近な脅威として理解しておくことが重要です。

Budibaseにおける脆弱性の詳細:Node.jsと`undici`の落とし穴

BudibaseはTypeScriptとNode.jsで開発されており、この脆弱性の根本原因はNode.jsアプリケーション特有の環境と、HTTPクライアントライブラリの利用方法にありました。

根本原因は主に二つ指摘されています。

1. **OpenAPIインポート機能の問題**<br>OpenAPIのURLをインポートする際、ホスト名のブラックリストチェック(プライベートIPではないことの検証)と、実際のHTTPフェッチが別々のタイミングで行われていました。この時間差がDNSリバインディングの隙を与え、検証時には外部IP、フェッチ時には内部IPへと切り替わることで、セキュリティチェックを回避されてしまったのです。

2. **RESTデータソース/クエリ実行機能の問題:`undici`のカスタム`dispatcher`**<br>BudibaseのREST機能では、既存のSSRF対策として「DNSピンニング」という手法を導入していました。これは、一度名前解決したIPアドレスを固定(ピン留め)し、それ以降はそのIPアドレスにのみ通信するようにすることで、DNSリバインディングを防ぐためのものです。しかし、BudibaseはHTTPクライアントとしてNode.jsのモダンな<code>undici</code>ライブラリを使用しており、さらにカスタムの<code>dispatcher</code>(通信経路を制御するコンポーネント)を利用していました。このカスタム<code>dispatcher</code>が、独自のDNS名前解決を再度行ってしまったため、本来ピン留めされていたはずのIPアドレスが無視され、新たな名前解決によって内部IPアドレスへと接続されてしまったのです。

`undici`のような高機能なHTTPクライアントライブラリは、Node.jsアプリケーションでパフォーマンスや信頼性を向上させるために広く利用されています。しかし、そのカスタム機能や内部的な挙動を深く理解せずに使うと、今回のようなセキュリティ対策が意図せず無効化されてしまうリスクがあることを示しています。

フロントエンド開発者が学ぶべき教訓と対策

このBudibaseの事例から、フロントエンド開発者も以下の点を学び、自身の開発に活かすべきです。

フロントエンドから外部APIを呼び出す際、ユーザー入力などによってURLが動的に生成される場合(例えば、ユーザーが指定した画像をダウンロードする機能など)、そのURLは常に厳しく検証されるべきです。特に、プロトコル(<code>http/https</code>)、ホスト名、ポート、パスなど、すべてホワイトリスト方式で許可されたパターンのみを受け入れるようにしましょう。安易なブラックリスト方式は抜け穴が見つかる可能性が高いです。

Node.jsベースのビルドツールや開発サーバー、あるいはLambda@Edgeのようなサーバーレス環境でNode.jsが動作する場面では、内部的なHTTPリクエストが発行されることがあります。<code>fetch</code> APIや<code>axios</code>、<code>undici</code>などのライブラリを使用する際には、DNS名前解決の挙動や、リダイレクト時の処理、カスタム<code>dispatcher</code>/<code>agent</code>の設定がセキュリティに与える影響を理解しておく必要があります。

信頼できる特定のホストにのみ接続する場合、一度DNSで解決したIPアドレスを固定する「DNSピンニング」や、そもそもIPアドレスで直接接続する(ただし証明書検証に注意)といった対策も有効です。また、<code>localhost</code>やプライベートIPアドレスへのアクセスは、原則としてアプリケーションレベルでブロックするべきです。

DNSリバインディングは、<code>localhost</code>で動く開発サーバーをターゲットに、攻撃者のWebサイトから悪意あるスクリプトを実行させ、開発者のPC内の情報にアクセスするといった攻撃にも利用されます。開発環境で不明なWebサイトを閲覧する際には注意し、また信頼できない外部リソースへのアクセスは避けるようにしましょう。

Budibaseの事例のように、セキュリティ対策を導入しても、新たなライブラリの導入やコード変更によって意図せず無効化されてしまうことがあります。DNSリバインディング、内部へのリダイレクト、IPv4-mapped IPv6アドレスなど、多様なシナリオをカバーする回帰テストを継続的に実施し、再発防止を徹底することが重要です。

まとめ

SSRFやDNSリバインディングは、一見するとフロントエンドとは遠い脆弱性に見えるかもしれません。しかし、Node.jsエコシステムの進化と開発プロセスの複雑化に伴い、フロントエンドエンジニアもサーバーサイドのセキュリティリスクに対する知識を深める必要性が高まっています。自身が関わるアプリケーションやツールが、どのように外部リソースと通信しているのかを理解し、常にセキュリティを意識した開発を心がけましょう。

この情報が、皆さんの日々の開発業務におけるセキュリティ意識向上の一助となれば幸いです。

← ブログ一覧に戻る