WordPress Tips | セキュリティ:ブラウザキャッシュのセキュリティ対応

web Web
スポンサーリンク

ブラウザキャッシュの「セキュリティ対応」とは何をすることか

まず前提から整理します。
ブラウザキャッシュ自体は「表示を速くするための仕組み」です。
しかし、扱うページの内容によっては“セキュリティリスク”にもなります。

特に問題になるのは、次のようなページです。

ログイン後のマイページ
会員情報・住所・メールアドレスが表示されるページ
注文履歴・請求情報・見積もり画面
管理画面に近い機能ページ

こういったページがブラウザや共有プロキシにキャッシュされると、

同じPCを使った別の人に見られる
共有端末(ネットカフェ・会社PCなど)で情報が残る
プロキシや中継サーバーに内容が保存され続ける

といったリスクが生まれます。

そこで出てくるのが、「キャッシュさせない/させ方を制御する」というセキュリティ対応です。


何が危ないのかを具体的にイメージする

共有PC・共用ブラウザでの「戻るボタン問題」

例えば、会員制サイトの「マイページ」を WordPress で作っているとします。

ユーザーAがログインして、自分のマイページを表示
その後ログアウト
同じPCを使ってユーザーBがブラウザの「戻る」を押す

もしそのページがキャッシュされていると、

ログアウト済みなのに、ユーザーAの情報が画面に残って見えてしまう

という状況が起こり得ます。

これは、

「サーバー側ではセッションが切れているのに、ブラウザが“保存していた画面”をそのまま見せてしまう」

という、キャッシュ特有の問題です。

共有プロキシ・中継サーバーに残り続ける問題

企業ネットワークや一部の環境では、

プロキシサーバー
CDN
中継キャッシュ

などが間に入ります。

ここに「個人情報を含むページ」がキャッシュされると、

本来その人だけのページが、別のユーザーに誤って返される
管理者や運用者がキャッシュを通じて中身を見られてしまう

といったリスクも理論上は存在します。


セキュリティ的に重要な Cache-Control の考え方

「速さ」ではなく「保存させない」ことが目的の設定

通常、パフォーマンス目的のキャッシュ設定では、

max-age
public
immutable

などを使って「できるだけ長くキャッシュしてほしい」と指示します。

一方、セキュリティ対応としてのキャッシュ制御では、方向性が真逆です。

「このページは保存しないでほしい」
「保存しても、他人に見せないでほしい」

というメッセージを、HTTPヘッダでブラウザや中継キャッシュに伝えます。

よく使うディレクティブの意味

ここは少しだけ“用語”を押さえましょう。

no-store

「このレスポンスは、どこにも保存してはいけない」

ブラウザキャッシュにも
共有キャッシュ(プロキシ・CDN)にも

一切保存させないという、最も強い指示です。
機密性の高いページでは、基本的にこれが本命です。

no-cache

名前が紛らわしいのですが、

「キャッシュしてもいいけど、使う前に必ずサーバーに確認して」

という意味です。
“保存禁止”ではありません。

private

「このレスポンスは“個人専用”なので、共有キャッシュには保存しないで」

ブラウザのローカルキャッシュには保存してよいが、
プロキシやCDNなど“複数ユーザーで共有されるキャッシュ”には保存させない、という指示です。


例題:どんなページにどんなキャッシュ制御をすべきか

例1:WordPress の管理画面・ログイン後の会員ページ

ここは「他人に見られたらアウト」な情報の塊です。

こういうページには、典型的にはこんなヘッダを付けます。

Cache-Control: no-store, private, must-revalidate
Pragma: no-cache

意味としては、

保存しないで(no-store)
もし保存されても共有キャッシュには置かないで(private)
再利用するときは必ずサーバーに確認して(must-revalidate)

という感じです。
Pragma: no-cache は古い HTTP/1.0 向けの“おまけ”としてよくセットで付けられます。

例2:一般公開のブログ記事ページ

ここは逆に「どんどんキャッシュしてほしい」側です。

Cache-Control: public, max-age=86400

のように、パフォーマンス重視の設定にします。

ポイントは「ページの性質によってキャッシュ戦略を分ける」ことです。
全部を一律 no-store にすると、セキュリティ的には安全でも、表示速度や負荷の面で損をします。


WordPress で意識したい「ブラウザキャッシュ × セキュリティ」の具体的な視点

ログイン後ページ・会員専用ページをどう扱うか

WordPress で会員制サイトやマイページを作るとき、

is_user_logged_in()
current_user_can()

などでログイン状態を判定して、
テンプレートやプラグイン側で「ログインユーザー専用の画面」を出すことが多いですよね。

このときに意識したいのは、

「ログインユーザー専用の画面は、キャッシュさせない」

という方針です。

PHP でヘッダを送るなら、イメージとしてはこんな感じです。

if ( is_user_logged_in() ) {
    nocache_headers(); // WordPress 標準のキャッシュ抑制ヘッダ出力
}
PHP

nocache_headers() は WordPress が用意している関数で、
Cache-ControlPragma などを「キャッシュさせにくい方向」に出してくれます。
機密性の高いページでは、これをベースにさらに no-store を追加する、という考え方もあります。

「戻るボタンで見えてしまう画面」を意識する

セキュリティ的に特に意識したいのは、

ログアウト後に「戻る」で見えてしまう画面
フォーム送信後に「戻る」で再表示される画面

です。

例えば、

注文確認画面
見積もり詳細
個人情報入力完了画面

などは、「もう一度見えなくてもいい/むしろ見えないほうが安全」なケースが多いです。

こういう画面には、

no-store を含む強めのキャッシュ制御ヘッダを付ける

というのが、セキュリティ的に筋の良い設計になります。


プログラミングの感覚で捉える「ブラウザキャッシュのセキュリティ対応」

これは「レスポンスのライフサイクルを設計する」話

アプリケーションの世界では、

このデータはどこに保存してよいか
どれくらいの期間保持してよいか
誰がアクセスできるべきか

を設計しますよね。

ブラウザキャッシュのセキュリティ対応は、

「レスポンス(HTML)のライフサイクルを、HTTPヘッダで設計する」

という行為です。

保存してほしいページ(公開記事)
保存してほしくないページ(個人情報・管理画面)

をきちんと分けて、
それぞれに合った Cache-Control を付ける——
これが“セキュリティ対応としてのキャッシュ制御”の本質です。

「全部 no-store」ではなく「ページごとに戦略を変える」

極端に言えば、

全部のページに no-store を付ければ、
キャッシュ由来の情報漏えいリスクはかなり減ります。

でもそれは、

CDNもブラウザキャッシュもほぼ効かない
毎回フルロードで遅いサイトになる

というトレードオフを意味します。

エンジニアとして良い設計は、

公開情報:パフォーマンス重視でキャッシュを活かす
機密情報:セキュリティ重視でキャッシュを抑制する

という「メリハリのあるキャッシュ戦略」を取ることです。


まとめ:ブラウザキャッシュのセキュリティ対応は「どのページを“残させないか”を決める設計」

「ブラウザキャッシュのセキュリティ対応」というテーマの本質は、

ログイン後ページや個人情報を含むページが
ブラウザや共有キャッシュに残り続けないようにし
他人に見られたり、誤配信されたりするリスクを減らす

ということです。

押さえておきたいポイントは、

キャッシュは速さの味方だが、機密ページでは“情報漏えいのきっかけ”にもなる
no-storeprivate などを使って「保存させない/共有させない」ことができる
WordPress では「ログイン後ページ」「マイページ」「管理画面」に強めのキャッシュ制御を意識する

という三つです。

一度、自分のサイトで「ログイン後に表示されるページ」「個人情報が出るページ」をリストアップしてみてください。
それらが“ブラウザに残っていてもいい画面か?”という視点で眺めると、
どこにキャッシュ制御を入れるべきかが、かなりクリアに見えてきます。

Web
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました