by
Anonymous Coward
on 2021年07月19日 17時01分
(#4074010)
時代に乗り遅れてる老害的な書き込みだなぁ それだと今流行のFastlyも使えなくなる
Reddit、Spotify、Twitch、Stack Overflow、GitHub、gov.uk、Hulu、HBO Max、Quora、PayPal、Vimeo、Shopify、Stripe、CNN、The Guardian、The New York Times、BBC、Financial Times これ全部 Fastly 使ってるぞ
MDN を信じずに「Cache-Control」には「private」を含めよう (スコア:1)
Web開発者がトップクラスとして信用しているサイトは MDN ですが、そこの Cache-Control の解説が酷いです。
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Cache-Control [mozilla.org]
にっこりしている顔文字🙂 [mozilla.org] 付きの「良い例」として
Cache-Control: no-store を挙げていて、
プンスカしている顔文字😡 [mozilla.org] 付きの「悪い例」として
Cache-Control: private,no-cache,no-store,max-age=0,must-revalidate,pre-check=0,post-check=0
を挙げていますが、「良い例」の方だと今回のような漏洩事故の原因となります。
今回の件が、このせいかどうかは分かりませんが、MDNを信じて情報漏えいが起きたケースは業界で割とよく耳にします。
ある程度の規模のサイトや、世界を対象としたサイトでは、CDNを使うのが今の常識です。
大手サイトでCDN使ってないケースなんてきわめてまれです。CDNを考慮していない解説は、セキュリティ上不適切です。
「レスポンスがどのキャッシュにも保存されないようにするには、代わりに no-store を使用してください。」(no-cache の解説より)
「no-store レスポンスをキャッシュに保存することはできません。他のディレクティブを設定することもできますが、最近のブラウザーではレスポンスがキャッシュされることを防ぐために必要なディレクティブはこれだけです。」(no-store の解説より)
特に上の解説が酷く「no-store」で「どのキャッシュにも」保存されないかのような書き方、つまりCDNもキャッシュしないかのような書き方をしていますが、
no-store を普通にキャッシュする CDN は非常に多いです。
ブラウザのキャッシュ制御とCDNのキャッシュ制御を分けられないと不便ですから、
「no-store」はブラウザ向けの指示、「private」は CDN やプロキシ向けの指示として扱われているのが、現状の実装のデファクトスタンダードです。
つまりは、どこにもキャッシュさせたくなければ「悪い例」の書き方が正解なのです。
「private」(これがあるとCDNはキャッシュしないか、CookieのセッションIDで同一の端末のみ有効なキャッシュとする)、
「max-age=0」(キャッシュの有効期限0秒としてキャッシュしないCDNも無いわけではないかもしれないが、基本はブラウザ向けの指示と解釈される)とCDNのキャッシュ無効化に役立つ項目もきちんと含まれています。
「pre-check」と「post-check」は IE5 の独自拡張でIE6で廃止されたはずなので今更必要ありませんが、あっても通信容量が25バイト無駄に消費される以外の害はありません。
なお、『「private」を含めよう』の対象は、個人情報などのユーザ個別のプライベートな情報を含む全てのページです。
プライベートな情報を含まないページにもつけたら、CDNが全ページキャッシュできなくなってCDNの役目が減ります。
(CDNによっては private を付けた場合はCookieのセッションIDをもとにそのユーザのみを対象としたキャッシュとして扱うこともあります)
※CDNが独自のヘッダー等でのキャッシュ設定をしている場合に、「no-store」かつ「private」でもキャッシュする場合があることは否定できません。
※CDNのマニュアルを読むことが重要なのですが、CDNで急に障害が発生して予定していない他のCDNに急いで乗り換えることになるケースとか、
急にDDoSを受けたとかで慌てて作業することになるケースが多いので、そういうケースも想定して乗換候補のCDNの説明書なども読んで色々なCDN向けのヘッダーを山ほど予めつけておくことが大切です。
Re: (スコア:0)
「no-store」でキャッシュするような CDN を使った時点で負けなんじゃないか?
メルカリの情報漏えいも「private」なら防げた (スコア:3, 興味深い)
CDN切り替え作業における、Web版メルカリの個人情報流出の原因につきまして
https://engineering.mercari.com/blog/entry/2017-06-22-204500/ [mercari.com]
問題発覚後に切り替え後CDNのキャッシュの仕様を再度確認したところ、キャッシュをしないのは
Cache-Control: private
が含まれている場合のみとわかりました。
「場合のみ」とあるので、「no-store」じゃ駄目で「private」の必要があるとあります。
CDN業者の名前は書かれていませんが、有名アプリのメルカリが使うような大規模なCDNでも、「no-store」無視の仕様だったりするのです。
また、
Expiresヘッダは、Cache-Controlヘッダにmax-ageまたはs-maxageがない場合採用されます。ただし、過去の日付である場合、0秒として扱われます。キャッシュの有効期限が0秒となる場合、CDNからオリジンへのリクエストの処理中に、同じURLに対してリクエストが発生すると、最初のレスポンスを待って、2つ目以降のリクエストにも同じレスポンスが返される仕様になっていました。
このため、お客さまがWeb版メルカリに対してアクセスを行い、メルカリのサーバがレスポンスを構築している途中で、別のお客さまから同じURLに対してリクエストがあった場合、レスポンスがまとめられ、最初のお客さまの情報がふくまれたコンテンツが別のお客さまへ配信される事態に至りました。
と、キャッシュ有効期限を0秒としても、「サーバがレスポンスを構築している途中」に次のアクセスがあると0秒扱いになってキャッシュが使われてしまって、それで情報漏えいが起きたようです。
ほんの一瞬でキャッシュの有効期限が切れるので、負荷テストのような大量アクセスをするテストでないと問題が再現せず発覚しにくいです。
皆さん誤解してます (スコア:0)
まともな議論になってないから、遅ればせながら指摘するけど、“CDNが”「Cache-Control: no-store」でキャッシュする仕様は正しい。そもそもCDNに対するディレクティブではない。「Cache-Control」フィールド自体、CDNが無い時代に作られた。「Cache-Control: private」はCDNが無断借用しているだけ。
CDNというのは、HTTP仕様としては違法や脱法的扱いのもの(違法改造)で、限定的に使われていたもの(動画配信やアップデート)が、スマホ・タブレットが普及したあたりから使うのが当たり前になったというものだと思う。
だから、 #4073928 の指摘は
Re: (スコア:0)
質問、CDNのどういうところがHTTPにとって違法あるいは脱法的なの?
HTTPにとってのCDNは https://datatracker.ietf.org/doc/html/rfc7230#section-2.3 [ietf.org] の"gateway" (a.k.a. "reverse proxy")に当てはまる存在であり、その存在自体に何か問題があるとは思っていなかったのだけど。
誤解しているのは「貴方」の方 (スコア:0)
これは酷い。
そもそも、ダイアルアップが主流の「インターネット」が高価だった時代は、キャッシュするプロキシの存在が一般的だったのじゃぞ。
会社・学校などの組織がそれぞれプロキシを運用していたのじゃ。
例えば、児童・生徒・学生がパソコン室から20台で同じサイトを見たら帯域がもたないから、公開のプロキシサーバがキャッシュして1回ですむようにしていたのだ。
当時有名なのは Squid というプロキシで、1996年 (25年前)からあったのじゃぞ。
その後、利用可能な帯域幅が増えて、組織がプロキシサーバを持たなくなってきて、その後、常時SSL化(TLS化)の流れでキャッシュがしにくくなって廃れていったというのが歴史の流れ。
ということで、大昔から Cache-Control で共有キャッシュの制御は行われていたし、RFCにもそれを想定した記述が山ほどある。
Re:MDN を信じずに「Cache-Control」には「private」を含めよう (スコア:1)
時代に乗り遅れてる老害的な書き込みだなぁ
それだと今流行のFastlyも使えなくなる
Reddit、Spotify、Twitch、Stack Overflow、GitHub、gov.uk、Hulu、HBO Max、Quora、PayPal、Vimeo、Shopify、Stripe、CNN、The Guardian、The New York Times、BBC、Financial Times
これ全部 Fastly 使ってるぞ
https://support.fastly.com/hc/en-us/community/posts/360040167351-Fastl... [fastly.com]
最初にキャッシュを行わない条件について理解しておきましょう。Fastlyサーバーでは以下の条件の場合はキャッシュを行いません。
・オリジンからのレスポンスにCache-Control: private が含まれている
(Cache-Control: no-store, no-cache はキャッシュ対象となります)
Re: (スコア:0)
Fastly が流行的で大手なのは認める(ついでに老害というのも認めよう)。
でも、事故の臭いのするものを使ってキャッシュ漏れるなら、別のサービス利用したら良くない?って私は考えるよ。
今流行のキャッシュは 0.2 秒 で消えるの (スコア:1)
何故 Fastly を使うのか [hatelabo.jp] を読んで欲しいんだけど、
「普通の CDN が数十秒?数分とかかるのにたいして 0.2 秒で全部消えることが保証されている」の部分が今 Fastly が流行ってる理由なの。
え、たった0.2秒? それ意味あるの? と思うかもしれない。
でも、よく考えて欲しいんだけど、それだと例えば掲示板やチャットサイトでも使える。
スラドのコメントだって反映に0.2秒かかっても問題ないからスラドでも問題なくキャッシュが活用できる。
0.2秒の遅延が許せない場合を除けば、リアルタイムのニュース配信だってなんだってキャッシュできるし、いちいちこのコンテンツは○分キャッシュして~なんて考えなくて良いわけ。
キャッシュサーバが0.2秒キャッシュしてくれるだけで、当該ページへのオリジンへのアクセスは秒間5回ですむ。
それならどんなへっぽこサーバだって当たり前に捌けるわけで、0.2秒もキャッシュしてくれれば実は十分なわけだ。
で、そうなるとブラウザキャッシュって邪魔だよね。
ブラウザの「戻る」を使ったときにもメモリキャッシュなんて使わずに最新(遅延0.2秒未満)の情報をロードして欲しい。
スラドだったら「戻る」で戻っても新しいコメントが反映されてた方がユーザが新しいコメントに気が付いて返信増えてサイトが盛り上がるかもしれない。
だとすると、自然とブラウザキャッシュを無効にしたくなるし、そのためには、
Cache-Control: no-store
とすることになる。(ちなみに、仮にブラウザキャッシュの有効期間1秒にしても、1秒以上経過した後でもブラウザの戻る・進む機能ではメモリキャッシュが使われることもあるので no-store にした方が確実)
それで Fastly のキャッシュも無効になったら不便なので、機密だからキャッシュして欲しくないコンテンツには、「private」の方を使って制御した方が便利、ということになる。
# RFC的には no-store をキャッシュするのはよくから、RFCに反する挙動に関する警告をもっとしっかり告知すべきだとは思うが。
しかし、CDN業者に関連RFC守れというのは、正直関係RFC自体が古臭くてどうしようもなくなっているからRFC守ったらイノベーションが破壊されるのが現状だと思う。
例えば、キャッシュ時間を制御するための max-age は、「秒」単位なんだよね。
https://datatracker.ietf.org/doc/html/rfc7234#section-1.2.1 [ietf.org]
「The delta-seconds rule specifies a non-negative integer, representing time in seconds.」とあるから小数点も使えない。
CDNのキャッシュを 0.2秒 にする時代に、キャッシュ時間指定に秒単位の整数で指定って、正直時代にそぐわない。あまりにも美しくない。
ってことで、
・「Cache-Control: no-store」でブラウザキャッシュは完全無効(更新しない png, css, js 等は除く)
・CDN のキャッシュ時間は全ページ 0.2秒
・個人情報を含むページは「Cache-Control: private」でCDNキャッシュ無効
のシンプル運用がお勧めなのです。
Fastlyは素晴らしいのでFastly使いましょう。
これが「別のサービス利用したら良くない?」への反論です。
Re: (スコア:0)
Fastlyの凄さの1つ、キャッシュが0.2秒で消えるというのはインスタントパージ(キャッシュ無効化するAPI叩く)の特長だろう。なので、そのシンプル運用だとFastlyでなければならない理由としては不十分に感じる。そういうただキャッシュTTL 0.2秒ならほかにもできるとこありそうに思うし、TTL 1秒に条件を緩めてよければだいたいどこのCDNでもできるに違いない。
Re: (スコア:0)
いまのインターネットは人類に対して複雑すぎるのかもしれないですね :D
MDNはあくまでブラウザの仕様について書かれているドキュメントなんで
ここにCDNを考慮した内容を載せるというのはちょっと期待し過ぎかなーと個人的には思います
もちろんそこまで考慮した内容になっているに越したことはないのですが...
CDNのドキュメントちゃんと読めというだけの話に思えるのですが
正直こんなのわからん人にはわからんような気がしていて
前にメルカリで事故ったやんと言ってもそれ知らない人にとっては一体何が悪かったのかわからない
(場合によっちゃあ間にCDN入ってることすら知らなかった可能性あ
Re: (スコア:0)
そのMDNのページ、「共有キャッシュ」「プロキシ」でページ内検索すると色々書かれているので、中途半端に共有キャッシュのことに触れているのが問題かと……
Re: (スコア:0)
キャッシュ制御に関係するHTTPヘッダー、Cache-ControlのほかにSurrogate-ControlとCDN-Cache-Controlもあり、そういえば自分はいつどうやって知ったんだっけ?みんなどうやって知るんだ?とか思う。
さらには、個人的なものだと慎ましくCDN使っておらず、NginxのX-Accel-ExpiresとX-Accel-Bufferingを考慮したりしなかったりする。
Re: (スコア:0)
MDNの内容に問題があるのならCDNの中の人か、問題意識を持っている当人が働きかけるべきなんじゃって気がしますね。
(GitHubで内容修正のプルリク出せるよね?)
CDNでの挙動についてMDNを悪者にするのは違うと思う。