[解説] Trigger.devに潜むプロトタイプ汚染の危険性:フロントエンドエンジニアも知るべきDoSの脅威
はじめに:Trigger.devの脆弱性とフロントエンドエンジニアへの影響
今回解説するGHSA-p28v-f755-9qrg / CVE-2026-73654は、オーケストレーションプラットフォーム「Trigger.dev」で発見されたプロトタイプ汚染の脆弱性です。これは主にサーバーサイドのAPIに関するものですが、アプリケーションが利用するライブラリの挙動や、サプライチェーン攻撃のリスクという観点から、フロントエンド開発者にとっても無関係ではありません。この脆弱性がどのように発生し、どのような影響をもたらすのかを技術的に深く掘り下げていきましょう。
プロトタイプ汚染 (Prototype Pollution) とは?
プロトタイプ汚染とは、JavaScriptにおいて`Object.prototype`などのグローバルなプロトタイプオブジェクトに、攻撃者によって任意のプロパティが追加・変更されてしまう脆弱性のことを指します。これにより、すべてのプレーンなオブジェクトがその汚染されたプロパティを継承してしまい、予期せぬ動作や脆弱性の連鎖を引き起こす可能性があります。フロントエンド開発でも、意図しない挙動やセキュリティホールにつながるため、この概念を理解しておくことは非常に重要です。
Trigger.devにおける脆弱性の詳細
本脆弱性は、Trigger.devの`run-metadata`更新エンドポイント`PUT /api/v1/runs/:runId/metadata`に存在します。このエンドポイントは、クライアントから提供される`"operations"`というデータ構造を受け取ります。問題は、この`operations`内の`operation.key`という、完全に攻撃者が制御可能な文字列が、`JSONHeroPath`ライブラリの`new JSONHeroPath(operation.key).set(newMetadata, value)`というメソッドに直接渡されてしまう点にありました。
`JSONHeroPath`ライブラリのバージョン`@jsonhero/path@^1.0.21`では、`__proto__`、`constructor`、`prototype`といったJavaScriptの予約語を、オブジェクトのプロパティパスとして無条件に処理してしまいます。そのため、攻撃者が`key: "$.__proto__.polluted"`のような値を指定すると、`Object.prototype.polluted`というプロパティがプロセス全体で設定されてしまい、グローバルなプロトタイプオブジェクトが汚染される状態となります。
深刻な影響:プロセス全体のDoSと他テナントの認証破壊
このプロトタイプ汚染は、共有のマルチテナントウェブアプリプロセス全体に深刻な影響を及ぼします。
**1. プロセス全体のDoS (Denial of Service)**: 汚染された`Object.prototype`は、PrismaクエリビルディングやPrometheusメトリクスクライアントなど、アプリケーションの様々な部分に影響を与えます。特に、Prometheusクライアント内で`uncaughtException`が発生し、ウェブアプリプロセスがクラッシュする可能性があります。これは、単一のリクエストでサービス全体を停止させることにつながり、攻撃者がリクエストを繰り返せば、継続的なクラッシュループを引き起こし、サービスを完全に利用不能にすることができます。
**2. 他テナントの認証破壊**: 共有のマルチテナント環境において、一つのテナントのAPIキーを持つ攻撃者によるプロトタイプ汚染が、他のテナントのワーカー認証を破壊する事象も確認されています。`prisma.runtimeEnvironment.findFirst`のような認証関連のデータベースクエリに汚染されたプロパティが意図せず混入し、`PrismaClientValidationError`を引き起こすことで、他のテナントのジョブ処理が停止します。
**3. さらなる攻撃の足がかり**: プロトタイプ汚染は、それ自体が直接的な情報漏洩やコード実行につながるだけでなく、より複雑な攻撃チェーン(例えば認証バイパスやロジック破壊など)を構築するための「原始的な足がかり」として悪用されるリスクも持っています。
影響を受けるバージョンと対策
**影響を受けるバージョン**: 本脆弱性は、`v3.3.8` (metadata operations API導入時) から`v4-beta`および現在の`v4.x`に至るまで存在していました。
**修正済みバージョン**: `4.5.6`で修正されています。Trigger.devを利用している場合、速やかにバージョンアップを実施することが強く推奨されます。
**開発者向け対策**:
1. **危険なパスセグメントの拒否**: `operation.key`のようなユーザー入力からパスを構築する際には、`__proto__`、`constructor`、`prototype`などの危険な予約語を明示的に拒否するバリデーションを導入してください。これはサーバーサイドだけでなく、フロントエンドでの入力検証においても同様に重要です。
2. **null-prototypeオブジェクトの利用**: メタデータオブジェクトを構築する際には、`Object.create(null)`を使用してプロトタイプを持たないオブジェクトを生成し、プロトタイプ汚染の影響を受けないようにする対策も有効です。
3. **ライブラリのアップグレードまたは代替**: 使用している`@jsonhero/path`のようなライブラリがプロトタイプ汚染に対して安全なバージョンであることを確認し、必要であればアップグレードするか、安全な代替ライブラリへの切り替えを検討してください。また、カスタムでセッターを実装する場合は、安全な実装を心がけましょう。
まとめ:サプライチェーンセキュリティと安全なコーディングプラクティス
今回のTrigger.devの脆弱性は、たとえサーバーサイドのコンポーネントであっても、利用しているライブラリの挙動や入力検証の不足が、サービス全体に壊滅的な影響を与えることを示しています。フロントエンドエンジニアも、自身が関わるアプリケーションが利用するライブラリやフレームワークのセキュリティ情報を常にチェックし、最新の状態に保つことの重要性を再認識すべきです。
また、ユーザーからの入力を扱う際には、常に「信頼できないデータ」として扱い、厳格なバリデーションを行うことが、プロトタイプ汚染のような攻撃を防ぐ上で不可欠です。安全なコーディングプラクティスを組織全体で徹底し、サプライチェーン全体のセキュリティ意識を高めていきましょう。