Shikata Ga Nai

Private? There is no such things.

区切り文字のズレ(エンコード文字 `%00` の利用)によるWeb Cache Deceptionの危険性

Hello there, ('ω')ノ

%00(ヌル文字)とは?

%00 は URL エンコードされた「ヌル文字(NULL byte)」です。

  • 通常の文字列処理において %00文字列の終了を意味する特別な文字です。
  • 一部のサーバーやフレームワークでは %00 によってパスを「途中で打ち切って」解釈します。

🧠 フレームワーク・キャッシュによる挙動の違い

🔹 オリジンサーバー(例:OpenLiteSpeed)

  • %00 を区切り文字として扱う
  • 例:/profile%00foo.js/profile にアクセスしていると見なす
  • 結果:動的なプロフィール情報などを含むレスポンスを返す

🔸 キャッシュサーバー(例:AkamaiやFastly)

  • %00 を特別な意味として扱わず、そのままパスとして解釈
  • foo.js のような静的ファイルの拡張子が含まれると、静的ファイルと見なしてキャッシュ対象にしてしまう

💥 実際の攻撃例

/profile%00foo.js
  • アプリケーション側/profile の動的レスポンスを返す(例:ログインユーザーの情報)
  • キャッシュ側.js 拡張子により「静的」と判断 → キャッシュに保存
  • 攻撃者が後から同じURLでアクセスして機密情報を取得

🚩 注意点:異常なURLと扱われる可能性もある

多くのモダンフレームワークやブラウザは %00 をブロックまたはサニタイズします。

システム %00 の扱い
OpenLiteSpeed 区切り文字として解釈する(脆弱)
Express.js / Django エラーとして返すケースが多い
Akamai / Fastly %00含めたパスをそのまま解釈 → キャッシュされる可能性

✅ この攻撃が成立するための条件

条件 内容
アプリが %00 を無視 or 切り捨てる OpenLiteSpeed など
キャッシュが %00 をそのまま使う .js を見てキャッシュ対象と判断
被害者をそのURLにアクセスさせる XSS, リンク, リダイレクトなどで誘導可能

✅ まとめ

%00(NULLバイト)を含むパスは、フレームワークとキャッシュで意味がズレるため、Web Cache Deceptionの温床となります。

観点 内容
オリジンサーバーの処理 %00でパスを打ち切り、/profileだけ処理
キャッシュサーバーの処理 %00foo.js全体を静的ファイルとして保存
リスク 機密情報が .js ファイルとして誰でも取得可能になる

Best regards, (^^ゞ