SvelteKitは人気のフルスタックJavaScriptフレームワークであり、Vercelはその最も一般的なデプロイプラットフォームです。この組み合わせで構築されたすべてのアプリが、他のサインイン済みユーザーの任意のルートからのレスポンスを攻撃者が読み取れる脆弱性を持っているとしたらどうでしょう?
ええ、事実です。この「キャッシュ欺瞞」と呼ばれる攻撃ベクトルは、まさにAikido テスト中にAIエージェントの1つが発見し報告したものです。当初は懐疑的でしたが、その手順を追跡したところ、脆弱性 再現できることが判明しました。私たちは直ちにVercelに通知し、現在では全ユーザー向けに脆弱性 自動的に脆弱性 。
注: 問題 は AikidoのIntelデータベース で確認可能であり、予約済みのCVE番号は次の通りです: CVE-2026-27118が割り当てられています。また、別の 問題 も発見しました。これはSvelteKitの実験的機能においてサービス拒否(DoS)を引き起こす可能性があります。この問題も開示され修正済みです。
クイックサマリー
会社情報 __パス名 SvelteKitのVercelアダプターにおけるクエリパラメータは、どこからでもパスを上書きできます。Vercelでは、以下のディレクトリ配下のすべてのファイルが対象となります。 /app/不変/ 異なる キャッシュ制御: ヘッダーを設定してキャッシュ可能にします。これに偽のパスを接頭辞として付加し、機密情報を含むように書き換えることで、レスポンスは強制的にキャッシュされます。これにより攻撃者は、クッキーなしで同じURLにアクセスするだけでレスポンスを取得できるようになります。
概念実証URL:
https://example.vercel.app/_app/immutable/x?__pathname=/api/session
検出
この物語は脆弱性発見したペンテスト の視点から、初期のガジェット発見から完全な悪用に至るまでを語り、その過程でいくつかの興味深いアイデアについて議論します。内なるロボットを受け入れ、さあ調査を始めましょう!
SvelteKitのソースコードを読むと、「アダプター」と呼ばれるものに出会うでしょう。これらはVercelのようなホスティングプラットフォームとSvelteKitフレームワークの間のミドルウェアです。これにより、プラットフォームの内部処理に必要なリクエストとレスポンスに特別なルールを適用することが可能になります。Vercelでは以下を実装しています: サーバーレス.js:
const DATA_SUFFIX = '/__data.json';
fetch(request) {
// If this is an ISR request, the requested pathname is encoded
// as a search parameter, so we need to extract it
const url = new URL(request.url);
let pathname = url.searchParams.get('__pathname');
if (pathname) {
// Optional routes' pathname replacements look like `/foo/$1/bar` which means we could end up with an url like /foo//bar
pathname = pathname.replace(/\/+/g, '/');
url.pathname = pathname + (url.pathname.endsWith(DATA_SUFFIX) ? DATA_SUFFIX : '');
url.searchParams.delete('__pathname');
request = new Request(url, request);
}
return server.respond(request, {
getClientAddress() {
return /** @type {string} */ (request.headers.get('x-forwarded-for'));
}
});
}
「これがISRリクエストの場合、要求されたパス名は検索パラメータとしてエンコードされる」と読み取れる。コードはこのパス名変数( ?__pathname= クエリパラメータ) を書き換えます。 url.pathname それと共に。リクエストは元のURLを無視し、単にこれを使用する __パス名 代わりに。
しかし、これらのインクリメンタル静的再生成(ISR)リクエストに関するチェックは存在しないようです。では、すべてのリクエストがこのパラメータをサポートしているのでしょうか?
答えはイエスであり、まさにそこに脆弱性 !クエリパラメータだけで、どのパスも他の任意のパスに上書きできる。例えば以下のような簡単なテストで確認できる: /?__pathname=/404 確かにホームページではなく404エラーが表示されるでしょう。

これは奇妙な機能に聞こえるかもしれません。なぜ危険なのでしょうか? ええ、キャッシュが関わるまでは危険ではありません。
キャッシュポイズニング?
もし任意のパスを他のリソースへリダイレクトできるなら、その改ざんされたリソースがキャッシュされたらどうなるか?これが我々の最初の考えでもあった。SvelteKitアプリのソースコードを確認すると、次のような記述が見られるだろう:
import("./_app/immutable/entry/start.CLO1Dlt2.js"),
import("./_app/immutable/entry/app.kQF6jJr8.js")
道 /app/immutable/entry/start.CLO1Dlt2.js 実行するJavaScriptを返します。そして、その応答を見ると、 キャッシュ制御: ヘッダーは確かにキャッシュされていることを示しています。これは静的リソースでは想定される動作です:
Age: 618
Cache-Control: public, immutable,max-age=31536000
X-Vercel-Cache: HIT
もし私たちが私たちの ?__pathname= パラメータを悪用してリクエストを書き換え、ファイルアップロードのような攻撃者が制御するパスを指すようにし、それでも同じプレーンテキスト形式でキャッシュされる。 /app/immutable/entry/start.CLO1Dlt2.js すべてのユーザーが読み込むパスであれば、全ユーザーにXSSが発生します。リクエストにこのクエリパラメータを追加するとどうなるか見てみましょう:
GET /_app/immutable/start.CLO1Dlt2.js?__pathname=/ HTTP/2
Host: example.vercel.app
応答では、ヘッダーから良い知らせと悪い知らせを受け取ります:
Age: 935
Cache-Control: public, immutable,max-age=31536000
X-Vercel-Cache: HIT
会社情報 年齢: 上記の段落を書くのにかかった時間だけ増加し、そして HIT 意味する クエリパラメータを追加して同じキャッシュエントリがヒットし、全員が読み込むものと同じになります。しかし同時に、それは古いJavaScriptコンテンツも返されることを意味し、書き換えられたパスのコンテンツではありません。その場合、キャッシュをフラッシュして最初にリクエストすることで、 私たちの 代わりにペイロードをキャッシュできますか?
残念ながらできません。Vercelプラットフォームはサーバーレスアーキテクチャのためより複雑であり、このような静的リソースに対してはアダプターコードにすら到達しません。静的アセットは上位レイヤーでキャッシュされ返されるため、それらを改ざんすることは絶対に不可能です。
この場合、脆弱性があるプラットフォームはVercelのみであるため、他の悪用可能なシナリオは見つかりません。行き詰まりました。
キャッシュの欺瞞!
次に、Webキャッシュのもう一つの問題点である「キャッシュ欺瞞」について説明する。このあまり知られていない手法では、攻撃者は被害者を、自身のクッキーで取得可能な機密ページへリダイレクトする。キャッシュがこのページを、どのユーザーがリクエストしたかを考慮せずに保存した場合、攻撃者は後で同じURLにアクセスし、キャッシュから被害者の個人データを閲覧できる。問題は、キャッシュがURLのみに基づいてレスポンスを保存し、異なるログインクッキーを持つ異なるユーザーが異なるコンテンツを見るべきだという点を無視している点にある。
この考えを私たちの ?__pathname= ガジェットを使えば、URLを作成できます 見える 静的なパスを指しているように見えるが、実際には機密性の高いコンテンツを指している。キャッシュ層は、その静的に見えるパスに基づいてトリガーされ、明示的な キャッシュ制御: ヘッダーを指定し、プライベートな応答を上書きする。
一方で キャッシュ基準 文書化されているが、我々の調査ではさらに多くの規則が明らかになった。既に周知の規則の一つ:パスが /app/不変/このプレフィックス下では、予想通り静的ファイルがキャッシュ可能であるだけでなく、 あらゆる 200 OK レスポンス。既に生成されたアセットを回避するため、最初は偽のアセットを指すように設定します。その後、任意の機密パス(例: api:
https://example.vercel.app/_app/immutable/x?__pathname=/api/session
これで最終的なペイロードが完成しました。被害者がログイン状態でこのリンクにアクセスすると、以下のようなリクエストが送信されます:
GET /_app/immutable/x?__pathname=apisession HTTP/2
Host: example.vercel.app
Cookie: auth=...
SvelteKitのVercelアダプターはパス名を書き換えます api, そしてアプリによって処理されます。 auth= クッキーが検証され、そのセッショントークンが返されます:
HTTP/2 200 OK
Age: 0
Cache-Control: public, immutable, max-age=31536000
...
Server: Vercel
X-Vercel-Cache: MISS
Content-Length: 16
{"token":"1337"}一方で キャッシュ制御: ヘッダーには通常 max-age=0 このエンドポイントでは、Vercelのキャッシュレイヤーが強制的にキャッシュを有効化します。 /app/不変/ 接頭辞
攻撃者が被害者がリダイレクトされたことを知ると、クッキーなしで同じURLを自らリクエストできるようになる:
GET /_app/immutable/x?__pathname=apisession HTTP/2
Host: example.vercel.app彼らは同じ反応を受ける HIT 現在、被害者のトークンを読み取ることができる。
HTTP/2 200 OK
Age: 22
Cache-Control: public, immutable, max-age=31536000
...
Server: Vercel
X-Vercel-Cache: HIT
Content-Length: 16
{"token":"1337"}
キャッシュバスター(一意のダミーパス)を使用し、リダイレクト後に確認することで、これは大規模に悪用される可能性がありました。脆弱性 、Vercel上のSvelteKitウェブサイトで認証にクッキーを使用している場合、任意のレスポンスを取得される可能性があります。
余波
私たちはすぐにこの問題をVercelに報告し、彼らは解決策を提案しました。 修正 あらゆるリクエストに対して強制的に404を返す /app/不変/ パスを削除し、 __パス名 パラメータ。プラットフォーム全体を管理しているため、この問題は全ユーザーに対して自動的に解決され、手動でのパッチ適用は不要です。
脆弱性 から脆弱性 大きな教訓脆弱性 キャッシュ処理は常に厄介だ脆弱性 。プレフィックス一致といった単純なルールでさえ、実装すらしていない予期せぬプラットフォーム機能によって悪用される可能性がある。
だからこそペネトレーションテストは非常に有用なのです。コードだけでは発見が難しいこのような問題は、実際のデプロイを通じて隠れたルールを発見し悪用することが可能です。Aikido ペンテスト、今回の問題を発見したように、キャッシュポイズニングやキャッシュデセプション攻撃を自動的に検知できます。
主要なポイント
- 2026年1月20日、 AikidoのAIペンテスト 、VercelにデプロイされたSvelteKitアプリケーションで興味深い点を検出しました。
- デフォルト設定脆弱性 キャッシュの欺瞞脆弱性 であることを確認しました。
- 設定ミスは不要です。SvelteKitとVercelが本来あるべき姿で機能するだけです。
- 影響: 認証済み応答はキャッシュされ、他のユーザーに公開される可能性があります。
- Vercel上で実行され、保護されたエンドポイントを持つSvelteKitアプリケーションは影響を受ける可能性があります。
影響を受けているか確認する方法
使用 Aikido:
もしあなたが Aikido ユーザーの方は、中央フィードを確認してください。この問題は Aikido Intelで問題を確認できます。ヒント: Aikido はリポジトリを毎晩再スキャンしますが、完全な再スキャンも手動で実行することをお勧めします。
Aikidoユーザーでない場合は、アカウントを設定し、リポジトリを接続してください。独自のマルウェアカバレッジは無料プランに含まれており、クレジットカードは不要です。
AikidoのAIペンテスト Webセキュリティスキャンペンテスト 、キャッシュ欺瞞フローや安全でない書き換え動作を自動的に検出します。
修正ステータス
当社は2026年1月21日にこの件をVercelに開示しました。
タイムライン
- 2026年1月20日: Aikido セキュリティ部門が脆弱性性を特定し、動作するPoCを構築
- 2026年1月21日:Vercelへの責任ある開示
- 2026年1月23日:報告書の優先順位付け
- 2026年2月9日:Vercelが報告を確認し、修正作業を開始する
- 2026年2月19日:Vercelは 脆弱性 修正し、アドバイザリを公開しました(GHSA-9pq4-5hcf-288c)。この問題は以下で確認できます AikidoのIntelデータベース で確認でき、予約済みのCVE番号は次のとおりです: CVE-2026-27118が割り当てられています。
また、別の 問題 を発見しました。これはSvelteKitの実験的機能においてサービス拒否を引き起こす可能性があります。この問題も開示され修正済みです。

