この記事は個人ブログに投稿した内容の再掲です。
Cache Storage がめちゃくちゃ肥大化する問題について調べる
---
Cache Storageがめちゃくちゃ肥大化する問題
TBSのニュースサイト、TBS NEWS DIGがめちゃくちゃブラウザのストレージを消費しているという話がはてなブックマークやはてな匿名ダイアリー(増田)で話題になっています。
確かに、手元でも同様の状況を観測できる。
はたして、これは真実なのだろうか。本当に1.4GBも食うことがあるのだろうか……
そんなわけない、ということで調査
まずは再現性を確認するためにChromeのゲストモードで当該のサイトのDevtoolを開いてましょう。すると、StorageのUsageは386MBになっていました。(適当なページを開き、リロードした時点で340MB程度であった)
上記のスクリーンショットをよく見ていただけるとわかると思いますが、このほとんどはCache storageが占めているのです。
元増田では
Cookie(LocalStorageとかも含むのか知らんけど)
https://anond.hatelabo.jp/20230426221025
となっていますが、今回問題なのはどちらでもなくCache storage。ちなみにLocalStorageは5MiBに制限されています。
Cache storageとは、PWAの文脈ではおなじみのServiceWorkerでブラウザのリクエストを中継し、このレイヤーでレスポンスをキャッシュ管理するために使うものです。(がばがばな説明)
当該サイトではGoogleのWorkboxというこれまたおなじみのライブラリが使用されています。
では、Cache storageの中身を見てみます。
Cache storageには記事内の画像などのmwcache-mwimages
、そしてスクリプトや各種リソースなどのmwcache-resources
といった2種類のキャッシュが存在しています。
しかし、これらのキャッシュを構成するResponseはいずれも大きくて数百KB、大半のものは10KBにも満たしません。つまり、これらを足したところで数百MBはおろか、10MBにも満たないことが分かります。
ではここにないものが計上されている?とも考えられるかもしれませんが、そういうわけでもないのです。
試しに消してみると、何かがおかしい
スクショをよく見てもらうと、Response-Type
という項目が opaque
と basic
の2種類あることがわかるかと思います。詳しい説明は後でするのですが、これが今回の問題のカギになります。
では、ここからこれがOpaqueとなっているものを1つ削除してみましょう。適当に1つ選択してDel または左上の×を押すだけです。
なんと、数KBのファイルを消しただけなのに5MBも減りました。
今回は5MBでしたが、7MBを中心に1MBだったり12MBだったりするようです。なぜ?
実はこれ、セキュリティ上のChromiumの実装
この問題について調べていると、あるStackOverflowのQ&Aにたどり着きます。詳しくまとまっている。
What limitations apply to opaque responses?
さきほどのOpaque Responseについての質問です。
Opaque、不透明なレスポンスというのは、クロスオリジンかつCORSでない、本来JS、ServiceWorkerからアクセスできなりリソースのレスポンスを指します。
ServiceWorkerはブラウザのレンダラに代わって(仲介して)リクエストをやりとりするわけなので中身は読み取れずとも、そういったリクエストを扱うことができます。
この質問では、当該するリソースの例として次のようなものが挙げられています。
What limitations apply to opaque responses?
<script>
<link rel="stylesheet">
<img>
,<video>
, and<audio>
<object>
and<embed>
<iframe>
ブラウザのストレージの使用量を取得するAPI navigator.storage.estimate()
は、こういったリソースについて不正確なPaddingをもった値を報告します。
SWの初期の初期の実装では、これは正確な値を返すように実装されていたようなのですが、Chromeの63あたりの特定のバージョン以降はPaddingを盛った値を報告するようになったというのです。これは以下のバグトラッカーの通り。
796060 – Cache Storage value rises on each refresh when Analytics code is in the html – chromium
セキュリティ上の理由から、Paddingを盛っているとのこと。
セキュリティ?どういう問題?
ここからは完全に推測に過ぎないわけですが、ファイル長からその中身が推定できると仮定すると、悪意のあるページで悪用が可能になる気がします。パスワード推定にそういったのを使う話もみかけますが、たとえばこれ、対策のガバい特定のサイトにユーザーがログインしているかどうかだって判定できる可能性があるのでは。。。?このあたりはセキュリティ詳しい方お願いします。
で、実際のディスク上のサイズは?
Cache storageの実体は当然Chromeのプロファイル内に存在します。
Chromeのプロファイル以下、 Service Worker/CacheStorage
に実体がありました。
たったの5MB前後!!!!!(Chromeでは1.4GBと出てる)
まとめ
- Chromeが報告するサイトごとのストレージ使用量は大嘘
- SWに通知するストレージ使用料はPaddingが1resあたり7MBほど乗ってる
- とはいえ設定UIにまでその値を使わないでほしい
参考
What limitations apply to opaque responses?
796060 – Cache Storage value rises on each refresh when Analytics code is in the html – chromium