
Shield SecurityのcookieがNginxキャッシュを止める時の解決策
Shield Security の icwp-wpsf-notbot cookie がサーバーのページキャッシュを妨害する問題は、Shield の設定で「silentCAPTCHA」の複雑度を「なし」にし、かつカスタムフィルターで匿名ユーザーへの cookie 送信を停止することで解決できる。
なぜ Shield Security が全ページでキャッシュを止めてしまうのか

Shield Security はボット判定や silentCAPTCHA の動作のために icwp-wpsf-notbot という cookie をフロントエンドの全ページで発行する仕様になっている。Nginx のキャッシュ機構は原則として Set-Cookie ヘッダを含むレスポンスをキャッシュしないため、この cookie がすべてのページキャッシュを無効化してしまう。結果として x-proxy-cache: MISS が返り続け、サーバーへのリクエストが毎回発生し、レスポンスタイムが 1000ms を超える状況に陥る。
サーバー側で特定の cookie だけをキャッシュ対象から除外する設定ができない場合、プラグイン側でこの cookie を止めるのが唯一の現実的な解決策になる。
管理画面で silentCAPTCHA の複雑度を「なし」にする

Shield Security の silentCAPTCHA は、ボット防御のためにフロントエンドのページにも cookie をセットする。設定を最小限に絞り込むには、まず管理画面から操作する。
これだけでは cookie の出力が止まらないケースが多い。Shield は silentCAPTCHA の設定に関わらず、フロントエンドの訪問者に対して一律に icwp-wpsf-notbot をセットする内部ロジックを持っているためだ。ここから先はコードレベルの対応が必要になる。
フィルターフックで匿名ユーザーへの cookie 送信を無効化する

Shield Security は icwp-wpsf-notbot cookie を制御するための専用フィルターを提供している。テーマの functions.php に数行のコードを追加すれば、ログインしていない一般訪問者に対する cookie の送信だけを停止できる。
functions.php に追加するコード
以下のコードを子テーマの functions.php に追加する。子テーマを使用していない場合は、Code Snippets プラグインなどで追加してもよい。テーマの直接編集はアップデートで消えるため避ける。
/**
* Shield Security の icwp-wpsf-notbot cookie をログインしていないユーザーには送信しない
*/
add_filter( 'icwp_shield_set_notbot_cookie', function( $set_cookie ) {
if ( ! is_user_logged_in() ) {
return false;
}
return $set_cookie;
} );このフィルターは icwp-wpsf-notbot cookie をセットする直前に呼び出される。ログインしていないユーザーの場合は false を返して cookie の発行をブロックし、ログイン済みユーザーには通常通り cookie を許可する。管理画面のログイン保護や IP ブロック、ファイアウォールなどのコア機能には影響しない。
動作確認の手順
- シークレットウィンドウでサイトにアクセスする
- ブラウザの開発者ツール(F12)→「アプリケーション」タブ→「Cookie」で
icwp-wpsf-notbotが存在しないことを確認する - レスポンスヘッダーから
Set-Cookieが消えていることを確認する - 2回目以降のアクセスで
x-proxy-cache: HITが返ることを確認する
全プラグインを最新に保って不要な干渉を防ぐ

Shield Security はアップデートの頻度が高く、バージョンによって内部のフィルター名が変更されることがある。Shield 22.1.3 および WordPress 7.0.1、PHP 8.2 環境では上記のフィルターが有効だが、プラグインが更新された際にはフィルター名が維持されているかを確認する必要がある。
また、キャッシュ系プラグインや CDN を併用している場合は、cookie 停止後にキャッシュを完全にクリアしてからテストすること。古いキャッシュが残っていると HIT になっていてもレスポンスが遅いままに見える場合がある。
よくある質問
SilentCAPTCHA を無効にしただけでは cookie は消えないのか
多くの場合、管理画面の設定だけでは cookie の出力は止まらない。Shield は silentCAPTCHA が無効でもフロントエンドの全リクエストに cookie をセットする内部挙動を持っている。確実に止めるにはフィルターフックの追加が必要だ。
このフィルターでログイン保護やファイアウォールは機能しなくなるか
今回のコードは匿名ユーザーへの icwp-wpsf-notbot cookie 送信だけを止めるもので、IP ブロックやブルートフォース保護、ファイアウォールといった Shield の主要防御機能はすべて通常通り動作する。ログインしたユーザーには引き続き cookie がセットされる。
functions.php を直接編集するのはリスクがないか
テーマの functions.php を直接編集すると、テーマのアップデートで変更が失われる。必ず子テーマを作成するか、Code Snippets のようなコード管理プラグインを使用する。また、コード追加前にサイトのバックアップを取得しておくと安全だ。
フィルターが効かない場合の確認ポイントは
Shield のバージョンが古い、あるいは逆に新しすぎてフィルター名が変更されている可能性がある。Shield の公式ドキュメントや変更履歴を確認する。また、キャッシュ系プラグインでサーバー側のキャッシュとは別にページキャッシュが残っていると、cookie 停止後も古いレスポンスが返り続けるため、すべてのキャッシュをクリアしてからテストする。
レンタルサーバーのキャッシュ設定で cookie ごとの除外はできないのか
共用サーバーの Nginx キャッシュ設定はサーバー全体で一律に適用されることが多く、特定の cookie だけを除外する柔軟な設定は提供されないケースがほとんどだ。サーバー側で対応できない以上、プラグイン側で cookie を止めるのが最も確実な方法になる。
この記事のポイント
- Shield Security の icwp-wpsf-notbot cookie が Nginx のページキャッシュを全面的に阻害する
- 管理画面で silentCAPTCHA の複雑度を「なし」にしても cookie は止まらない
- functions.php にカスタムフィルターを追加しログインしていないユーザーへの cookie 送信を停止する
- フィルター追加後はシークレットウィンドウで Set-Cookie ヘッダーと x-proxy-cache の値を確認する
- プラグインのアップデート後はフィルター名の変更に注意しキャッシュを完全クリアして再テストする

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

Cloudflare Workers Cache登場、Worker専用キャッシュでコスト削減
Workers Cache の登場でCloudflare Workersが「オリジン」から「静的配信」へ進化

CloudflareがWorkers Cacheを正式にリリースした。これは単なるキャッシュ機能の追加ではない。Workersのアーキテクチャを根本から覆し、コストとパフォーマンスのトレードオフを解消する大きな転換点だ。一言で表せば「あなたのWorkerの前に、そのWorker専用のキャッシュを置ける機能」である。
1行の設定を追加するだけで、Workerが生成したレスポンスはCloudflareのエッジネットワークにキャッシュされる。キャッシュが有効な間はWorkerそのものが実行されず、CPU時間の課金もゼロになる。これは特に、サーバーサイドレンダリング(SSR)を行うアプリケーションにとって、待望のソリューションだ。
本記事では、なぜこの機能が必要とされていたのか、具体的に何が変わるのか、そして開発者がどのように活用できるのかを詳しく解説する。
問題: Workerがオリジンの場合、処理のたびにコードが実行され、キャッシュの恩恵を受けにくい。
効果: レスポンスが高速化し、WorkerのCPU実行コストが削減される。
この図が示すように、Workers Cacheはリクエストの最前線に立つ。これにより、Workerが事実上のオリジンサーバーとして振る舞う現代的なアプリケーションのパフォーマンスとコスト構造が劇的に改善される。
なぜサーバーサイドアプリに「Workerの前のキャッシュ」が必要だったのか

Workerが「経由点」から「オリジン」へ変わった世界
2017年のリリース当初、Cloudflare Workersはオリジンサーバーの手前でリクエストを書き換える「中間処理層」として設計された。A/Bテストの振り分けやヘッダーの追加といった、軽量な処理をエッジで実行するユースケースが中心だったのだ。当時、Workerはキャッシュよりもさらにオリジンに近い位置にあった。
しかし状況は一変した。AstroやNext.js、SvelteKitといった主要フレームワークが、ビルド成果物をCloudflare Workersで直接動かすアダプターを提供し始めたのである。これにより、Workerはもはや単なる中継点ではない。アプリケーションそのものがWorker上で動作する「サーバー」になった。裏側に別のオリジンサーバーは存在しなくなり、Worker自体がリクエストを処理するようになったのだ。
この変化は大きな問題を生んだ。従来のアーキテクチャでは、Workerがオリジンになると、すべてのリクエストがコードの実行を必要とするようになる。たとえ1秒前と全く同じHTMLを返す場合でも、だ。これはパフォーマンス上のレイテンシと、無視できないCPU実行コストを常に発生させることを意味していた。
静的生成と動的レンダリングのジレンマを解決する第三の道
この問題に対し、開発者はこれまで2つの選択肢から選ぶしかなかった。
- 静的サイト生成(SSG):すべてのページをビルド時に事前生成する。表示は高速だが、コンテンツを更新するたびに全ページを再ビルドする必要がある。数千ページのサイトでは、このビルド時間が大きなボトルネックになる。
- サーバーサイドレンダリング(SSR):リクエストのたびにページを動的に生成する。コンテンツは常に最新だが、全てのアクセスでレンダリングコストとレイテンシが発生する。
Workers Cacheはここに第三の選択肢、つまり「オンデマンドでサーバーレンダリングし、結果をキャッシュし、指定したTTL(生存期間)で更新する」という新しい手法を提供する。最初のリクエストだけがレンダリングコストを支払い、後続のリクエストはキャッシュから静的ファイルのように配信されるのだ。これはフレームワーク独自の複雑な仕組み(ISRなど)に依存しない、HTTP標準に則った解決策である。
パフォーマンスを極める主要機能「SWR」と「Vary」の内部動作

stale-while-revalidate が「待ち時間ゼロ」を実現する仕組み
Workers Cacheの真価を引き出すのが、stale-while-revalidate(SWR)ディレクティブだ。これはキャッシュされたレスポンスがTTLを超過した「古い(Stale)」状態でも、とりあえずその古いデータをユーザーに返しつつ、バックグラウンドで最新のデータを取得し直すHTTPの仕組みである。
SWRがない場合、キャッシュの有効期限が切れた後の最初のリクエストは、必ずWorkerが一からページをレンダリングするまで待たされる。しかしSWRがあれば、この最初のリクエストに対しても古いキャッシュが即座に返され、ユーザーは待ち時間を感じない。Workers CacheはこのSWRを完全にサポートしており、これによって「動的なサイトなのに、まるで静的サイトのように感じる」という体験を実現している。
この図の通り、SWRはTTLが切れた後の「最初の一人」が被る待ち時間を帳消しにする。Cloudflare Blogの記事によれば、Cloudflareは今年の早期にこのSWR機能をフルサポートしており、Workers Cacheはその上に構築されていることがわかる。
Vary ヘッダーが複数の表現をキャッシュする
現実のアプリケーションは、同じURLでもクライアントに応じて異なるレスポンスを返す必要がある。例えばブラウザにはHTMLを、APIクライアントにはJSONを返す場合や、対応状況に応じてWebPとJPEGを出し分ける場合だ。Workers Cacheは、このコンテンツネゴシエーションをHTTP標準のVaryヘッダーで解決する。
WorkerがVary: Acceptというヘッダーを付けてレスポンスを返すと、Cloudflareは「Acceptリクエストヘッダーの値」ごとに別々のキャッシュエントリを自動で作成・管理する。これにより、WebPに対応したブラウザにはWebP画像のキャッシュが、そうでない環境にはJPEG画像のキャッシュが返るようになる。開発者は複雑なキャッシュキーの設定を意識する必要はなく、標準的なHTTPのルールに従うだけで、安全かつ効率的に複数表現をキャッシュできるのだ。
開発者が知っておくべき設計思想「ゾーンではなくWorkerのキャッシュ」

エントリーポイント単位の柔軟なキャッシュ制御
Workers Cacheの最も革新的な部分は、それが「ゾーン(ドメイン)」ではなく「Worker」に紐づくという設計思想にある。この思想が、従来のCDNでは実現できなかったいくつもの高度なユースケースを可能にしている。
特に重要なのが、Workerのエントリーポイントごとにキャッシュの有効・無効を設定できる点だ。設定ファイルでエクスポート名("default"や"CachedBackend")を指定するだけで、認証処理を行うゲートウェイWorkerはキャッシュを無効化し(常にコードを実行するため)、その背後で重い処理を行うバックエンドWorkerだけにキャッシュを有効化する、といった構成が可能になる。
このエントリーポイント単位の制御により、キャッシュはアプリケーションアーキテクチャの一部として自然に組み込めるようになる。単一のWorkerの中に、キャッシュするレイヤーとしないレイヤーを共存させ、それらをコードで自在に結合できるのだ。これは、CDNキャッシュを単一のオリジンの前に置くという従来の考え方とは一線を画す。
マルチテナントを安全にする ctx.props の仕組み
ユーザーごとに異なる情報を返すAPIのキャッシュは、セキュリティ上の大きな課題を伴う。ユーザーAのキャッシュがユーザーBに見えてしまうような事故は、絶対に避けなければならない。Workers Cacheはこの問題を、ctx.propsの一部を自動的にキャッシュキーに含めることで根本的に解決している。
例えば、ゲートウェイWorkerで認証したユーザーIDをctx.propsにセットし、キャッシュが有効なバックエンドWorkerを呼び出すとする。Workers Cacheはこの「ユーザーID」の違いを認識し、ユーザーごとに完全に独立したキャッシュ空間を作り出す。これにより、「認証済みAPIはキャッシュできない」という固定観念を覆し、ユーザー単位で安全にレスポンスをキャッシュできるようになる。Cloudflare Blogによれば、これは他の主要CDNでは提供されていない、Workers Cache独自の強力な利点だという。
Workers Cacheがもたらすプラットフォームとしての進化
パフォーマンスとデータの近接性を両立するアーキテクチャ
Webパフォーマンスにおいては、コードを「ユーザーの近く」で実行するのと「データの近く」で実行するのは、しばしばトレードオフの関係になる。Workers Cacheはこのジレンマに対して、キャッシュを「糊(にかわ)」として利用する解決策を提示する。
具体的には、次のような構成が現実的になる。ユーザーの近くで動き、認証やルーティングといった軽量な処理を担当するWorker Aを配置する。一方、データベースへの重いクエリやレンダリングを実行するWorker Bを、Smart Placement機能でデータの近くに配置する。Workers Cacheは、このWorker Bの手前にのみ配置する。
リクエストが来ると、Worker Aが処理した後、サービスバインディングを通じてWorker Bを呼び出す。この時、Worker Bのキャッシュがヒットすれば、データの近くにあるWorker Bは実行されることなく、ユーザーの近くにあるキャッシュからレスポンスが返る。キャッシュミス時のみ、実際のデータへのアクセスが発生する。これにより、「ユーザー近接性」と「データ近接性」の良いとこ取りが可能になるのだ。
フレームワークとの統合とコストの透明性
Workers CacheはすでにAstroフレームワークのアダプターでネイティブサポートされている。設定ファイルに数行追加するだけで、ページ単位のTTLやタグベースのキャッシュパージが利用できる。TanStack StartやNext.js(Vinext経由)など他のフレームワークへの統合も現在進行中だ。
コスト面も明快だ。Workers Cacheのキャッシュヒット時は、通常のリクエスト課金は発生するが、WorkerのCPU実行時間に対する課金はゼロになる。キャッシュストレージに対する追加のGB単位の課金もないため、コスト削減効果を予測しやすい。ダッシュボードでは、キャッシュヒット率やヒット/ミス/バイパスの内訳が確認でき、パフォーマンスチューニングに必要なデータが一元管理されている。
この記事のポイント
- Workers Cacheは、Workerの手前に専用の階層型キャッシュを配置する新機能である。
- これにより、サーバーサイドアプリが静的サイトのような速度を実現しつつ、CPU実行コストを削減できる。
stale-while-revalidateの完全サポートにより、キャッシュ更新中もユーザーを待たせない。- ゾーンではなくWorkerに紐づく設計により、エントリーポイント単位で柔軟なキャッシュ戦略をコードで記述できる。
ctx.propsをキャッシュキーに含めることで、マルチテナント環境でも安全なキャッシュが実現する。

・ 複数業界における17年間のデジタルビジネス開発経験
・ ウェブサイト開発のためのHTML、PHP、CSS、JavaScript等の実用的知識
・ 15ヶ国語対応の多言語SaaSの開発経験
・ 17年間にも及ぶ、Eコマース長期運営経験
・ 幅広い業界でのSEO最適化の豊富な経験

WordPressのアコーディオンブロックが開かない原因と直し方
WordPress 6.9のアコーディオンブロックをクリックしても展開しない場合は、ページ読み込み時にブロックのJavaScriptが正しく初期化されていないことが原因だ。キャッシュを完全に削除し、プラグインの競合を確認することで大半のケースは解決する。改善しない場合はテーマの読み込み順を調整する。
なぜアコーディオンブロックが展開しないのか

この現象は、アコーディオンブロックの内部で使われる view.min.js が、ページの読み込み完了前にクリックイベントを受け取ってしまうことで起きる。具体的には、ブロックの状態(開閉のデータ)がまだ存在しないタイミングで「開く」処理が実行され、「未定義のプロパティを読めない」というTypeErrorが発生するという仕組みだ。
読み込み速度が極端に速い場合も、逆に特定のスクリプトが遅延して遅くなった場合も、内部のタイミングがずれて初期化が完了しないまま操作できてしまう。Twenty Twenty-Fiveテーマに限らず、他のテーマやプラグインがページの読み込み順を変えていると同様の症状が出ることがある。
c が undefined → エラーJavaScriptエラーの原因を開発者ツールで確認する方法
まずエラーが出ているか正確に把握する。ChromeやEdgeのデベロッパーツール(F12キー)を開き、Consoleタブを確認する。該当ページでアコーディオンをクリックした瞬間に赤いエラーメッセージが出ていれば、今回の症状に合致する。
エラー文は日本語環境でも英語で「Uncaught TypeError: Cannot read properties of undefined (reading ‘isOpen’)」と表示される。ファイル名に view.min.js が含まれていれば、WordPress 6.9の標準アコーディオンブロックの初期化問題だと特定できる。
アコーディオンが開かない場合の5つの対処法

以下の手順は、簡単で効果が高いものから順に並べている。1つずつ試し、改善した時点で後続の手順は不要だ。
サイト全体のキャッシュを完全に削除する
キャッシュ系プラグイン(W3 Total CacheやWP Super Cacheなど)を導入している場合は、管理画面から全キャッシュを削除する。加えてサーバー側のキャッシュ(NGINX FastCGI CacheやLiteSpeed Cache)もクリアする。ブラウザキャッシュを個別に消すよりも、プラグインやサーバー管理パネルからの一括削除のほうが確実だ。
全プラグインを無効化して原因を特定する
プラグインのいずれかがJavaScriptの読み込み順やタイミングに干渉している可能性がある。「プラグイン」→「インストール済みプラグイン」からすべてのプラグインを一時的に無効化し、アコーディオンブロックの動作を確認する。問題が解消したら、1つずつ有効に戻していき、再発するプラグインを特定する。
この方法で原因プラグインが判明した場合、そのプラグインの代替を探すか、開発元に修正を依頼するのが現実的だ。特にJavaScriptを多用するページビルダーや最適化系プラグインは干渉しやすいので注意する。
テーマの状態をリセットする
子テーマやカスタマイズを行っている場合は、一時的に親テーマのTwenty Twenty-Fiveに直接切り替える。必要に応じて「外観」→「テーマ」から親テーマを有効化し、カスタマイザーで追加した独自のCSSやJavaScriptが干渉していないか切り分ける。
functions.phpでスクリプト読み込み順を調整する
上記の手順で解決しない場合、テーマやプラグインの読み込み順が影響している可能性が高い。子テーマの functions.php に以下のコードを追加し、WordPress標準のスクリプトをより早い段階で読み込ませる方法が有効だ。
<?php
function force_accordion_script_priority() {
if ( has_block( 'core/accordion' ) ) {
wp_enqueue_script( 'wp-block-library' );
// モジュールスクリプトの読み込みを優先
add_filter( 'script_loader_tag', function( $tag, $handle ) {
if ( false !== strpos( $handle, 'accordion' ) ) {
$tag = str_replace( 'defer', '', $tag );
}
return $tag;
}, 10, 2 );
}
}
add_action( 'wp_enqueue_scripts', 'force_accordion_script_priority', 5 );
このコードは、アコーディオンブロックがページ内に存在する場合にだけ動作し、defer 属性を除去して読み込みの優先度を上げる。極端な遅延読み込みが原因でエラーが起きている場合に効果を発揮する。
そもそもこのエラーが起きる条件とは

このエラーはWordPress 6.9の標準ブロックに含まれる view.min.js のタイミング依存が直接の原因だ。以下のような条件が重なると発生しやすい。
- 高速なサーバー環境やCDNによってHTMLの描画が極端に速い
- 最適化プラグインがスクリプトに
deferやasyncを追加している - ページビルダーが独自の方法でスクリプトを結合・遅延読み込みしている
- カスタムテーマが
wp_head()やwp_footer()を正しく呼び出していない
いずれも、WordPressが想定するスクリプトの読み込み順序が変更されることで、ブロックの状態管理オブジェクトが生成される前にクリックイベントのリスナーが機能し始めてしまう点で共通している。
再発を防ぐための設定ポイント

この問題を恒久的に避けるには、スクリプト最適化の設定を見直すのが最も効果的だ。キャッシュプラグインや高速化プラグインの「JavaScriptの遅延読み込み」「結合」「minify」などの機能を無効化するか、該当ブロックだけ除外設定を追加する。
具体的には、プラグインの設定画面で「遅延読み込みの除外」に view.min.js または accordion を含むパスを指定する。多くの高速化プラグインでは、特定のスクリプトハンドルやファイル名を除外リストに登録できる。
また、WordPressのアップデートによってコア側の修正が入る可能性も高い。そのため、WordPress本体とテーマは常に最新の状態を維持し、修正が公式にリリースされ次第適用することも大切だ。
よくある質問
特定のブラウザだけで起きるのか
いいや、ブラウザの種類よりもページの読み込み速度やスクリプトの実行順序に左右される。Chrome、Edge、Firefox、Safariのいずれでも発生しうる。特定のブラウザだけで再現する場合は、ブラウザ拡張機能の影響も疑うとよい。
プラグインをすべて無効にしても直らない場合は
テーマに原因がある可能性が高い。一度Twenty Twenty-Fiveの親テーマを直接有効化し、それでも改善しなければサーバー側のキャッシュ機構やCDNの設定を見直す。functions.phpに追加したカスタムコードが干渉しているケースもある。
キャッシュをクリアしても改善しないときの次の手順は
ブラウザのシークレットウィンドウでテストし、ブラウザキャッシュを完全に排除した状態で確認する。それでも同じエラーが出るなら、上記のSTEP 4のコード追加を試すか、WordPress本体の再インストールを検討する。
このエラーはWordPressのバグなのか
厳密にはタイミング依存のバグであり、WordPress 6.9に標準で含まれる view.min.js に起因する。今後のアップデートで修正される見込みだが、現時点ではサーバー環境やプラグイン構成によって発生が左右されるため、回避策を講じるのが現実的だ。
テーマ側で何かできることはあるか
ある。先述のfunctions.phpによる defer 属性の除去のほか、テーマが wp_footer() の直前に不要なスクリプトを挿入していないか確認することも有効だ。シンプルなテーマほどこの問題は起こりにくい。
この記事のポイント
- アコーディオンが開かない原因はJavaScript初期化のタイミングずれ
- キャッシュの全削除とプラグイン全無効化でほぼ修正できる
- 改善しなければfunctions.phpでスクリプト優先度を上げる
- 最適化プラグインの設定で
view.min.jsを除外登録する - WordPress本体とテーマは常に最新版を保つ

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

W3 Total Cache 2.10.0 更新後に動的コンテンツが表示されない時の直し方
W3 Total Cache 2.10.0 へのアップデート後、動的コンテンツが表示されず「W3TC dynamic mfunc tag refused: missing call:slug + hmac envelope.」と表示される場合、根本原因はバージョン 2.10.0 で導入された HMAC 署名検証の仕様変更である。プラグインを 2.9.x 系に戻すか、動的ブロックの呼び出しコードに正しい slug 属性と HMAC 署名を付与すれば直る。
どんな症状が発生しているのか

W3 Total Cache(以下 W3TC)のページキャッシュを有効にしたサイトを更新したあと、AdRotate Pro など mfunc タグを使って動的コンテンツを部分キャッシュしていた箇所が、エラーメッセージに置き換わる。日本語環境では英文のまま「W3TC dynamic mfunc tag refused: missing call:slug + hmac envelope.」という文言が表示されるケースが多い。この文言は「mfunc 呼び出しが拒否された。slug と HMAC エンベロープが不足している」という意味だ。
対象になるのは、W3TC のページキャッシュ機能と「後期キャッシング(Late Caching)」や「動的 mfunc ブロック」を組み合わせて使っていたサイトである。具体的には、固定ページ全体をキャッシュしつつ、広告ブロックやログイン状態表示などの一部だけを非キャッシュで差し込んでいた構成だ。更新前は問題なく動いていたのに、2.10.0 にした途端に該当箇所だけエラー文言に化ける。
なぜ W3TC 2.10.0 でエラーが起きるのか

W3TC 2.10.0 では、動的 mfunc タグのセキュリティ強化として HMAC(ハッシュベースのメッセージ認証コード)による署名検証が必須になった。これは不正な動的コードの注入を防ぐための仕組みだが、従来の呼び出しコードには slug 属性と HMAC 署名が含まれていなかったため、検証に失敗し、一律で拒否されるようになった。
W3TC の動的 mfunc ブロックは、PHP 関数をページキャッシュ内に埋め込んでおき、キャッシュから配信される直前に実行する仕組みだ。これまでは単純なコールバック名だけで動作していたが、2.10.0 からは「どのスラッグから呼び出されたか」と「正当な呼び出し元であることを証明する HMAC 署名」のセットがなければ mfunc タグが無効化される。
この仕様変更は W3TC 本体のセキュリティアップデートであるため、AdRotate Pro など W3TC 互換モードを持つ他プラグインの側が新しい署名形式に対応していないと、もれなくエラーになる。結果的に、更新後は互換モードで動的コンテンツを提供しているほとんどすべてのサイトで同じ問題が発生している。
すぐにサイトを元に戻す応急処置

W3 Total Cache を 2.9.x 系にダウングレードする
最も短時間で確実に直す方法は、W3TC を 2.10.0 より前のバージョンに戻すことだ。ダウングレード手順は以下のとおり。
- 管理画面の「プラグイン」から W3 Total Cache を停止する
- 「プラグイン」→「プラグインの追加」→「プラグインのアップロード」を使うか、FTP で古いバージョンの ZIP を展開して上書きする
- プラグインを再有効化し、すべてのキャッシュを削除する
古いバージョンの ZIP ファイルは WordPress.org のプラグインページにある「以前のバージョン」セクションから入手できる。バージョン 2.9.8 や 2.9.9 であれば HMAC 署名検証が存在しないため、従来どおり動的 mfunc タグが動作する。
ダウングレードしたあとは、W3TC の自動更新を一時的に停止することを推奨する。管理画面の「プラグイン」で個別に自動更新をオフにするか、wp-config.php に define( 'AUTOMATIC_UPDATER_DISABLED', true ); を追加してサイト全体の自動更新を止めておけば、意図しない再アップデートを防げる。
他プラグインの W3TC 互換モードを一時的に無効化する
もし AdRotate Pro など、W3TC 互換モードを個別にオン・オフできるプラグインを使っているなら、当該プラグインの設定で互換モードをオフにする手もある。ただしこの場合、ページキャッシュの影響で広告がローテーションしなくなったり、動的コンテンツが静的になってしまったりする副作用がある。あくまで「エラー表示を消す」ための一時的な回避策と位置づけるのが安全だ。
2.10.0 を使い続ける場合の恒久対応

W3TC 2.10.0 のセキュリティ修正を活かしたまま動的コンテンツを動作させるには、呼び出しコードに正しい slug と HMAC 署名を付与する必要がある。この修正は、動的 mfunc タグを生成している側(多くの場合は広告管理プラグインや自作のテーマ関数)に手を入れることになる。
W3TC の HMAC 署名の仕組みを理解する
mfunc タグはページキャッシュの HTML 内に PHP コード片を残し、キャッシュ配信時に W3TC がそれを検出して実行する。2.10.0 ではこのとき、呼び出しパラメータとして「call:slug」と「hmac」の両方がエンベロープに含まれていなければならない。slug は処理を一意に識別する任意の文字列、hmac は W3TC 内部で生成される署名ハッシュだ。
生成ルールは公開されているが、実際には W3TC が提供する API 関数を使って動的ブロックを登録するのが現実的だ。自作テーマであれば w3tc_fragmentcache_register フィルターを使い、コールバックと slug を W3TC に登録すれば、あとは W3TC 側が自動で HMAC 署名を計算してくれる。
AdRotate Pro での対応状況を確認する
AdRotate Pro は W3TC 互換モードを有効にしている場合、内部的に mfunc タグを生成している。今回のエラーは、AdRotate Pro が生成する mfunc タグが 2.10.0 の新形式に対応していないために発生している。AdRotate Pro の開発元がこの問題に対応したアップデートをリリースするまでは、互換モードの使用が難しい。
AdRotate Pro の管理画面にある「W3 Total Caching compatibility」設定をオフにし、代わりに JavaScript による非同期広告読み込み(AdRotate のダイナミックモード)を使うか、広告ブロックを iframe で埋め込む形に切り替えると、ページキャッシュ機構に依存せず動的広告を配信できる。
自作テーマで動的ブロックを登録し直す
テーマの functions.php などで自作の動的コンテンツを mfunc タグで埋め込んでいた場合は、W3TC のフラグメントキャッシュ API を使った正式な登録に切り替える。基本的な流れは次のとおりだ。
w3tc_fragmentcache_registerフィルターで、slug とコールバック関数のペアを W3TC に登録する- テンプレート内では
w3tc_fragmentcache_output関数を使い、slug を指定して動的出力を行う - W3TC が自動で HMAC 署名を計算し、mfunc タグとしてページキャッシュに埋め込む
この方法なら、W3TC のバージョンが上がっても署名方式の変更に W3TC 本体側が追随するため、サイト側のコードを再度修正する必要がなくなる。フラグメントキャッシュ API の具体的な記述例は W3TC の公式ドキュメントに掲載されている。
Late Caching 設定の確認と調整
W3TC の pgcache.late_caching 設定(後期キャッシング)が有効かどうかも、動作に影響を与える要素のひとつだ。この設定が true の場合、ページ生成の最終段階で mfunc タグを処理するため、プラグイン間の競合が減る傾向がある。すでに true でもエラーが出ている場合は今回の本質的な原因ではないが、念のため設定値を確認しておく。
wp-content 内の w3tc-config/master.php を直接確認するか、管理画面の「パフォーマンス」→「一般設定」からエクスポートした設定ファイルで pgcache.late_caching の値を確認できる。false であれば true に変更し、キャッシュを全削除してから表示を再確認する。
再発を防ぐための注意点

W3TC のような深くサイト機構に組み込まれるプラグインをメジャーバージョンアップする前には、必ずステージング環境で検証する習慣をつける。とくに mfunc やフラグメントキャッシュといった、通常のキャッシュとは異なる高度な機能を使っている場合は、本番適用前に動的コンテンツの全パターンをテストする必要がある。
また、W3TC の設定をエクスポートしてバックアップしておけば、問題が起きたときに設定ごと以前のバージョンに戻せる。管理画面「パフォーマンス」→「一般設定」の下部にある「設定のダウンロード」ボタンで、JSON 形式の設定ファイルを定期的に保存しておくとよい。
よくある質問
「W3TC dynamic mfunc tag refused」はサイト全体が真っ白になるのか
サイト全体が真っ白になるわけではない。ページの大部分は正常にキャッシュ配信されるが、mfunc タグで差し込まれていた動的コンテンツの部分だけがエラー文言に置き換わる。レイアウトが崩れることはあるが、PHP 致命的エラーによる白画面とは異なる。
キャッシュを削除しても直らないのはなぜか
キャッシュ削除はあくまで「現在保存されているキャッシュファイルを消す」行為であり、mfunc タグの生成コード自体を修正するものではない。新しいキャッシュが生成されるときに、同じく新形式に対応していない mfunc タグが再度埋め込まれるため、キャッシュ削除だけでは根本解決にならない。
W3TC 無料版でも同じ問題は起きるのか
起きる。HMAC 署名検証は W3TC のコア機能の一部として Pro 版・無料版の両方に実装されている。フラグメントキャッシュや mfunc タグを使っているサイトは、Pro 版かどうかに関係なく影響を受ける。
このエラーを放置してもサイトには大きな問題はないか
動的コンテンツが表示されないという機能面の問題に加え、エラー文言が来訪者にそのまま見える状態はサイトの信頼性を損なう。また広告が表示されなければ収益にも直結するため、実質的には早期解決が必要な重大トラブルに分類される。
他に W3TC 2.10.0 で影響を受けるプラグインはあるか
AdRotate Pro 以外にも、W3TC 互換モードで動的コンテンツを埋め込む仕組みを持つプラグイン全般が影響を受ける可能性がある。具体的には、動的ウィジェットやパーソナライズ表示を行うキャッシュ対応プラグインが該当する。該当プラグインの更新情報を注視し、開発元が W3TC 2.10.0 対応を表明するまではアップデートを保留するのが安全だ。
この記事のポイント
- W3TC 2.10.0 の HMAC 署名検証強化で mfunc タグが拒否される
- ダウングレードで即時解決するがセキュリティ面は旧版に戻る
- 互換プラグイン側の対応アップデートを待つか公式 API で再実装する
- キャッシュ削除だけでは再発するため mfunc コード自体の修正が必要
- メジャーアップデート前のステージング検証と設定バックアップが再発防止の鍵

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

WooCommerceアナリティクスでOops something went wrongエラーが出た時の直し方
WooCommerce を 10.6.1 にアップデートした直後、アナリティクス概要に「Oops something went wrong」と表示され、ブラウザコンソールに TypeError: t(…)(…).tz is not a function というエラーが記録される場合、JavaScript のタイムゾーンライブラリを巡るプラグイン競合か、キャッシュの不整合が原因だ。まず全プラグインの無効化と標準テーマへの一時的な切り替えで原因を特定し、競合するプラグインを見つけ出すことから始める。
なぜ WooCommerce アナリティクスで tz is not a function エラーが起きるのか
WooCommerce の管理画面アナリティクスは、内部的に Moment.js とそのタイムゾーン拡張を使い、日付や時間の演算をおこなっている。10.6.1 では JavaScript アセットの読み込み順や依存関係に変更が入ったため、別のプラグインやテーマが同じ Moment.js タイムゾーンライブラリを異なるバージョンで読み込んでいる場合に .tz メソッドが上書きされるか、存在しない状態になり、今回の TypeError が発生する。
また、ブラウザやサーバー側のキャッシュに古いスクリプトが残っていると、管理画面で本来動くはずの新しいコードと混ざり、同様のエラーが出ることもある。まずは「どの拡張機能やテーマが影響しているか」を切り分けるのが近道だ。
エラーの原因を特定する手順

上図の手順で、問題の切り分けができる。WooCommerce 本体だけを有効にした状態でアナリティクスが正常に動けば、あとは再有効化の過程でエラーを再現させるプラグインを見つければよい。
全プラグインを無効化して競合を確認する
「プラグイン」→「インストール済みプラグイン」画面で、全てのプラグインにチェックを入れ、「一括操作」から「停止」を実行する。WooCommerce だけは残すか、最初はすべて停止し、その後 WooCommerce だけ有効化し直す。この状態で管理画面の「WooCommerce」→「アナリティクス」を開き、エラーが出ないか確認する。
テーマを Storefront など標準テーマに切り替える
有効化しているテーマの functions.php やフックが、管理画面の JavaScript 読み込みに干渉しているケースは意外に多い。「外観」→「テーマ」で Storefront や Twenty Twenty-Five など公式の軽量テーマに一時的に切り替え、同じくアナリティクス画面を確認する。
ブラウザキャッシュとサーバーキャッシュをすべて削除する
キャッシュ系プラグイン(W3 Total Cache、WP Rocket など)を使っている場合は管理画面からキャッシュを全削除する。さらにブラウザでシークレットウィンドウ(プライベートブラウジング)を開き、そちらで管理画面にログインしてテストすると、ローカルキャッシュの影響を排除できる。サーバー側で OPcache や Redis オブジェクトキャッシュを導入している場合は、それらのクリアもおこなう。
プラグインを1つずつ再有効化して原因を突き止める
無効化状態でエラーが消えたら、プラグインを1つ有効化するごとにアナリティクス画面を再読み込みし、エラーの再発をチェックする。再現したプラグインが競合元だ。よくあるのは、カスタムレポート系、日付や予約管理、多言語対応(WPML や Polylang)、ページビルダーの管理画面用スクリプトを追加するタイプのプラグインだ。
競合するプラグインを特定したあとの恒久対策

原因のプラグインが判明しても、サイト運営上どうしても外せない場合がある。そのときは、問題のスクリプトだけを管理画面のアナリティクスページでのみ読み込まないようにする手がある。
以下のコードを子テーマの functions.php に追加すると、特定のスクリプトをアナリティクス画面で解除できる。ここでは例として「moment-timezone」ハンドルを一旦解除し、WooCommerce が想定する正しいバージョンを再登録する方法を示す(実際のハンドル名は競合元により異なるため、ブラウザのデベロッパーツールで確認する)。
add_action( 'admin_enqueue_scripts', function( $hook ) {
if ( false === strpos( $hook, 'woocommerce_page_wc-analytics' ) ) {
return;
}
wp_dequeue_script( 'moment-timezone' );
wp_deregister_script( 'moment-timezone' );
wp_enqueue_script( 'moment-timezone', includes_url( 'js/moment-timezone.min.js' ), array( 'moment' ), null, true );
}, 100 );この例では WordPress 本体バンドルの moment-timezone を読み直しているが、WooCommerce が読み込むパスとは異なる場合がある。より安全なのは、競合プラグイン側の更新を待つか、Asset CleanUp 系のプラグインで該当スクリプトを該当ページでのみブロックする方法だ。
それでも直らない場合の応急処置としての WooCommerce のロールバック
どうしてもすぐにエラーを止めたいときは、WooCommerce を問題のなかったバージョン(例:10.5.2)に戻す方法がある。無料プラグイン「WP Rollback」を使えば、管理画面からワンクリックで以前のバージョンにダウングレードできる。
「プラグイン」→「新規追加」で WP Rollback をインストールし有効化すると、プラグイン一覧の WooCommerce に「ロールバック」リンクが現れる。そこから 10.5.2 を選択し、ロールバックを実行する。ただし、これは一時しのぎであり、セキュリティ修正などが含まれている場合はリスクがあるため、問題の根本解決を優先する。
よくある質問
プラグインをすべて無効化してもエラーが消えないのはなぜか
テーマの functions.php や子テーマに管理画面用のスクリプトを追加している可能性が高い。必ず標準テーマ(Storefront や Twenty Twenty-Five)に切り替えて確認する。また、ブラウザ拡張機能やサーバー側のキャッシュが残っている場合もエラーが継続する。
キャッシュを削除しても改善しない場合はどうするか
ブラウザのシークレットウィンドウを使うか、別のブラウザでテストする。サーバー側で OPcache や Varnish、CDN のキャッシュが効いている場合は、そちらも合わせてクリアする。WP CLI が使えるなら wp cache flush も試す。
特定のプラグインが原因とわかったが、そのまま使い続けたい
プラグイン開発元に WooCommerce 10.6.1 への対応状況を問い合わせ、アップデートを待つのが最も確実だ。緊急時は、前述のコード例や Asset CleanUp で競合を回避する方法があるが、サイト全体の動作確認を十分におこなったうえで適用する。
WooCommerce をダウングレードしても問題ないか
ダウングレードすると、10.6.1 で修正されたセキュリティ上の問題や不具合が再発する可能性がある。あくまで原因究明と修正が終わるまでの一時的な措置と考え、早急に恒久対策を講じる。
同じエラーがフロントエンドのカートやチェックアウトでも出る
管理画面だけでなくフロントエンドでも同様の TypeError が発生する場合、テーマかキャッシュプラグインの JavaScript 最適化機能(結合・圧縮)が原因になっていることが多い。キャッシュプラグインの設定で JavaScript の結合を一時的に無効にし、テーマを標準テーマに切り替えて症状が消えるか確認する。
この記事のポイント
- WooCommerce 10.6.1 でアナリティクスに tz is not a function エラーが出るのは JavaScript のタイムゾーンライブラリ競合かキャッシュ不整合
- プラグイン全無効化+標準テーマへの切り替えで原因を特定し、1つずつ再有効化して競合プラグインを特定する
- 競合プラグインが見つかったら、更新を待つか functions.php でスクリプトを制御する
- 緊急時は WP Rollback で WooCommerce を一時的にダウングレードできるが、恒久対策が優先

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

メガメニューのスタイルが崩れた時の原因と直し方
プラグイン更新後にメガメニューのスタイルが崩れ、一部のナビゲーション項目が表示されなくなった場合、まずは以前のバージョンへの巻き戻しと全キャッシュの削除を試みる。この2つで多くのケースは即座に復旧する。
なぜプラグイン更新後にメガメニューのスタイルが崩れるのか

メガメニュープラグインは、独自の CSS と JavaScript を読み込んでスタイルを適用している。アップデートによってこれらのファイル構成が変更されると、ブラウザやサーバーに残った旧バージョンのキャッシュが新バージョンのスタイルと衝突し、見た目が崩れることがある。
また、プラグイン内部で HTML 構造が変更された場合、テーマ側で追加したカスタム CSS のセレクタが合わなくなり、スタイルが外れてしまうケースも少なくない。これが「項目が完全に見えなくなる」原因になることもある。具体的には、項目を非表示にする CSS ルール(display:none など)が誤って適用されたり、z-index の競合で他の要素の裏に隠れたりする。
メガメニューの崩れを直す緊急対処の流れ

まずはサイトの表示に直接影響するキャッシュをすべて取り除き、それでも直らなければプラグインを以前のバージョンに戻す。この順序で作業すると、無駄な切り分けを減らせる。
キャッシュを完全に除去する手順
まず Chrome や Firefox のデベロッパーツールを開き、ネットワークタブで「キャッシュを無効化」にチェックを入れた状態で再読み込みする。これでブラウザキャッシュ由来の崩れかどうかをすぐに確認できる。改善したらブラウザキャッシュが原因だ。
次に WordPress の管理画面から、使用しているキャッシュ系プラグイン(WP Rocket や W3 Total Cache など)の設定画面を開き、「キャッシュをすべて削除」を実行する。さらに「CSS の最適化」や「JavaScript の結合」機能が有効なら、一度無効化してからキャッシュを再生成する。結合・最適化の過程で生まれた旧ファイルが新バージョンと衝突している可能性があるためだ。
サーバーレベルで Nginx や Varnish を使っている場合は、ホスティングのコントロールパネルからサーバーキャッシュもフラッシュする。
プラグインを以前のバージョンに巻き戻す
キャッシュの完全削除でも直らないときは、アップデートそのものに互換性の問題があると判断してよい。メガメニュープラグインを無効化し、旧バージョンの ZIP ファイルを入手して手動で上書きする。
旧バージョンはプラグインの公式ページにある「以前のバージョン」セクションや、開発者向けの SVN リポジトリからダウンロードできる。管理画面の「プラグイン」→「新規追加」→「プラグインのアップロード」から ZIP を選び、「既存のものを置き換える」形でインストールする。上書き後、管理画面でバージョン表記が古くなっていれば成功だ。
この作業でメガメニューが復旧したら、一時的に自動更新を停止しておく。プラグイン一覧画面や wp-config.php に define('WP_AUTO_UPDATE_CORE', false); を追加する方法もあるが、該当プラグインだけを止めるにはプラグイン単位の自動更新を無効化するコードを functions.php に書くか、管理プラグインを使う。
項目がまるごと消える問題の原因を切り分ける

スタイル崩れだけでなく、メニュー項目のひとつが完全に非表示になるケースでは、CSS の display プロパティや visibility プロパティが悪さをしていることが多い。HTML 構造が変わった結果、テーマ側で追加したカスタム CSS が意図しない要素を非表示にしている可能性がある。
デベロッパーツールで非表示の原因を特定する
Chrome の検証機能で消えたメニュー項目の HTML 要素を探す。要素が見つかるのに画面に出ていない場合は、右側の「スタイル」パネルで display:none や visibility:hidden が適用されていないか確認する。該当プロパティがあれば、打ち消し線が入っているか、どの CSS ファイルの何行目から来ているかが表示される。
もしテーマの style.css や追加 CSS に身に覚えのないルールがあれば、そのセレクタがアップデート後の HTML に誤ってマッチしている可能性が高い。一時的にそのルールをコメントアウトして表示が復活するかを試すと、原因の特定が早い。
テーマとプラグインの競合を調べる
メガメニュープラグインのアップデート後に問題が起きた場合、テーマ側のメニュー処理と競合していることも考えられる。一時的に標準テーマ(Twenty Twenty-Five など)に切り替えて、メニューが正常に表示されるか確認する。標準テーマで問題なければ、テーマ側のカスタマイズや専用のメニュー関数が干渉していると判断できる。
再発を防ぐためのアップデート前チェックリスト

メガメニューのようなサイト全体の導線を担うプラグインは、更新ひとつで売上や問い合わせに影響が出る。以下の手順を踏んでおけば、今回のようなスタイル崩れを未然に防げる。
- ステージング環境で事前にアップデートを検証する
- テーマのカスタム CSS はメガメニューのクラス名に依存しすぎない
- 更新前に必ずサイト全体のバックアップを取る
- キャッシュ系プラグインの設定を更新後に見直す習慣をつける
特に、ステージング環境での事前検証は手間に見えて最も確実な安全策だ。多くの国内レンタルサーバーはワンクリックでステージングを作れる機能を備えている。更新後、メニューの表示やモバイルでの開閉動作を一通りチェックしてから本番に反映すれば、今回のような急なスタイル崩れでサイトが長時間壊れる事態を回避できる。
よくある質問
旧バージョンの ZIP が見つからない場合はどうする?
プラグインの公式ディレクトリページ下部にある「以前のバージョン」からダウンロードできないケースでは、開発者の公式サイトや GitHub リポジトリを探す。WP Rollback のようなプラグインを使えば、管理画面から直接過去のバージョンに切り替えられる場合もある。
キャッシュを削除しても直らないのはなぜ?
サーバー側のキャッシュに加え、CDN を使用している場合は CDN のキャッシュもパージする必要がある。また、ブラウザの Service Worker が古いファイルを保持していることもあるので、シークレットウィンドウで確認するか、デベロッパーツールから Service Worker の登録を解除する。
アップデートを戻したのに一部のスタイルが直らない
旧バージョンに戻した後も、キャッシュ系プラグインが生成した最適化済み CSS ファイルが残っている可能性がある。「CSS の再生成」や「クリティカル CSS の削除」も実行する。さらに、テーマ側のカスタマイザーで追加した CSS が悪さをしていないか、追加 CSS 欄を一時的に空にして確認する。
修正版がリリースされるまでどう運用すればよい?
プラグインの自動更新を停止し、旧バージョンのままサイトを運用する。管理画面の「更新」通知は無視して問題ない。修正版が公開されたら、最初にステージング環境でテストし、スタイルや項目の表示に問題がないことを確認してから本番に適用する。
この記事のポイント
- プラグイン更新後のメガメニュー崩れはキャッシュの完全削除から試す
- 改善しなければ旧バージョンに巻き戻し、自動更新を一時停止する
- 項目消失は CSS の意図しない適用が原因になりやすい
- テーマとの競合を疑う場合は標準テーマで切り分ける
- 再発防止にはステージング環境での事前検証が最も有効

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

WooCommerce 11.0が商品オブジェクトキャッシュを標準化!新規ストアは自動有効
WooCommerce 11.0がリリースされ、商品オブジェクトキャッシュが新規ストア向けにデフォルトで有効化された。この機能は、商品ページやチェックアウト処理で同じ商品データを何度もデータベースから取得する無駄を省き、ECサイトの表示速度を底上げする。
可変商品がある製品ページでは約9〜12%、バンドル商品を含むチェックアウト処理では6〜12%の処理速度改善が報告されている。今回の変更は、WooCommerce 10.5で実験的導入が始まったキャッシュ機構が安定動作の段階に達したことを示している。
新規にWooCommerce 11.0以上をインストールしたストアには自動で適用されるが、アップグレードした既存ストアの設定は一切変更されない。必要に応じて管理画面から手動でオンにできる仕組みだ。
商品オブジェクトキャッシュの仕組みとパフォーマンス改善の数字

リクエスト内で商品データを使い回すメモリ内キャッシュ
このキャッシュは、一度のHTTPリクエストの間だけ生きている、揮発性のメモリ内キャッシュだ。wc_get_product(123)が呼ばれると、キャッシュに保存されていればデータベースに問い合わせず、すぐに商品オブジェクトの複製を返す。リクエストが終わればキャッシュは完全に消去されるため、次のリクエストで古い情報が残る心配はない。
特に、wc_get_product()を同じIDで何度もコールするパターンが多いテーマやプラグインで効果が大きい。各呼び出しが独立したオブジェクトのクローンを返すため、意図せず商品データの状態を共有してしまうバグも防げるようになった。
このデモは、同じ商品IDに対する繰り返し呼び出しがキャッシュによってどれだけ無駄を省けるかを示している。実際のECサイトでは、商品ループやセール情報の取得、決済フローの中で wc_get_product() が頻繁に呼ばれるため、体感速度の改善が期待できる。
実測値として9〜12%の高速化
WooCommerce 10.5の実験的導入時に公表されたパフォーマンス測定値は、今回の正式適用後も同じだ。可変商品(サイズや色のバリエーションがある商品)の製品ページでは、読み込み時間が9〜12%短縮された。バンドル商品を含むチェックアウト処理では6〜12%高速化されている。
この改善幅は、商品データを繰り返し取得する重いクエリがページ表示のボトルネックになっている状況で顕著だ。小規模なサイトでは効果が体感しにくいケースもあるが、商品数が多いストアや複雑な製品構成のサイトでは、目に見える速度向上が得られる。
WooCommerce 10.5から11.0への段階的な導入プロセス

10.5で実験的機能として登場、10.6で互換性の宣言が「互換」に
商品オブジェクトキャッシュは、WooCommerce 10.5で「実験的機能」として初めて公開された。当時はデフォルトで無効であり、ストア運営者が手動でオンにする必要があった。機能自体は、wc_get_product()の呼び出しをインターセプトし、リクエスト単位のメモリ内キャッシュからデータを返す仕組みだ。
WooCommerce 10.6では、この機能のプラグイン互換性宣言が「非互換」から「互換」に変更された。実験期間中に拡張機能エコシステム全体で互換性の問題が一切報告されなかったため、明示的に互換性を宣言していない拡張機能も、デフォルトで互換とみなされるようになった。
もし拡張機能が明示的に「この機能とは非互換」と宣言している場合は、WooCommerceの機能画面に従来通り非互換の通知が表示される。しかし、そのような宣言が必要になった拡張機能は見つかっていない。
11.0で新規ストアへの自動有効化を実装
WooCommerce 11.0のクリーンインストール時には、インストールプロセスの一環として商品オブジェクトキャッシュが自動で有効になる。機能登録自体は enabled_by_default => false のまま変更されていないが、新規インストール時に明示的に有効化が書き込まれる仕組みをとっている。
これは、HPOS(High-Performance Order Storage)など、他の機能がオプトインから新規インストール時デフォルトへ移行した際と同じパターンだ。バージョンアップだけでは既存ストアの設定を変更しない、慎重な設計が貫かれている。
既存ストアの挙動と手動有効化の手順

アップグレードしても設定は一切変わらない
WooCommerce 11.0より前に構築されたストアは、11.0へアップグレードしても既存のキャッシュ設定がそのまま維持される。もし以前に無効だった(それが11.0以前のストアのデフォルト設定だ)なら、アップグレード後も無効のままだ。すでに手動で有効にしていたストアは、そのまま有効が継続される。
つまり、次の3パターンに整理できる。
- WooCommerce 11.0以降を新規インストール → 自動的に有効(操作不要)
- 既存ストアで機能が無効だった → アップグレード後も無効のまま(手動で有効にできる)
- 既存ストアで機能が有効だった → アップグレード後も有効のまま(操作不要)
手動で有効化する方法
既存ストアでこの機能を試したい場合、管理画面の WooCommerce → 設定 → 詳細設定 → 機能 にアクセスし、「商品オブジェクトをキャッシュする(Cache Product Objects)」のトグルをオンにすればよい。ただし、設定変更後にサイト全体の動作を一通りチェックしておくことが推奨される。
トグルをオンにすると、その瞬間からリクエスト単位の商品キャッシュが働き始める。とくに、複数の拡張機能が同じ商品データにアクセスする大規模ストアでは、即効性のある改善が期待できるだろう。
拡張機能開発者への影響と注意点

標準APIを使っていればコード変更は不要
wc_get_product() やその他 WooCommerce 標準 API を通じて商品を取得している拡張機能は、このキャッシュの影響をまったく受けない。キャッシュは内部で透過的に動作し、呼び出し元には変わらず正しい商品オブジェクトが返る。
キャッシュから返されるのは、あくまで独立したクローンなので、取得した商品オブジェクトを編集しても他の処理に副作用が及ぶことはない。したがって、従来のコーディング規約に従っている拡張機能は、そのまま動作し続ける。
直接SQLを実行する拡張機能が注意すべきポイント
注意が必要なのは、WooCommerceのメタフックを経由せずに、商品データに対して直接SQLクエリを発行している拡張機能だ。これらのクエリはキャッシュの無効化フックを迂回するため、更新後のデータがキャッシュに反映されず、古い情報が返ってしまう可能性がある。
この問題は、商品オブジェクトキャッシュに限った話ではなく、WooCommerceのデータ整合性全般に関わる設計課題だ。該当する拡張機能を開発している場合は、標準の wc_get_product() やメタデータ更新用のAPIを使うことで、キャッシュの恩恵を受けつつ、データ不整合も回避できる。
今後のロードマップと全ストアへの有効化計画

データ蓄積後に全ストアで有効化へ
今回のリリースは通過点であり、最終的にはすべてのストア(既存ストアも含む)で商品オブジェクトキャッシュを有効化する計画が示されている。現時点で具体的な実施時期は明言されていないが、十分なストアでの稼働データが蓄積された段階で判断される。
すでに実験期間で問題が報告されていないこと、新規インストールのデフォルト有効化でさらなる実績が積み上がることを踏まえると、早ければ数バージョン後には全ユーザー対象の強制有効化に踏み切る可能性が高い。
問題が発生した場合の報告先
もし商品オブジェクトキャッシュに関連して予期せぬ挙動が見つかった場合、WooCommerceのGitHubリポジトリでIssueを報告してほしいと開発チームは呼びかけている。拡張機能開発者やストア運営者からのフィードバックが、今後の安定化に直結する。
この記事のポイント
- WooCommerce 11.0 で商品オブジェクトキャッシュが新規ストア向けに自動有効化された
- 可変商品の製品ページ読み込みは 9〜12% 高速化、バンドル商品のチェックアウトは 6〜12% 改善
- 既存ストアはアップグレードしても設定変更なし、管理画面から手動でオンにできる
- 標準の WooCommerce API を使う拡張機能はコード変更不要で動作する
- 最終的には全ストアで有効化される予定で、Issue 報告を募っている

・ 複数業界における17年間のデジタルビジネス開発経験
・ ウェブサイト開発のためのHTML、PHP、CSS、JavaScript等の実用的知識
・ 15ヶ国語対応の多言語SaaSの開発経験
・ 17年間にも及ぶ、Eコマース長期運営経験
・ 幅広い業界でのSEO最適化の豊富な経験

JavaScriptがログアウト時に動かない原因と直し方
管理画面にログインしているときだけ JavaScript が動き、ログアウトすると止まる。この現象の原因は、ほぼ「スクリプトの読み込み順序」と「キャッシュ・最適化プラグインの挙動」のどちらか、あるいは両方の組み合わせだ。ログイン時は管理バー用のスクリプト等が読み込まれるため依存関係が偶然成立し、ログアウト時にそれが外れてエラーになるケースが多い。
ログアウト時だけ JavaScript が動かなくなる仕組み

このデモは典型的な依存関係の崩れを示している。ログイン中は WordPress が管理バーやフッターに jQuery を読み込むため、その後に記述されたスクリプトが偶然動く。ログアウトすると jQuery が存在せず、$ is not defined や jQuery is not defined といったエラーで止まる。
HTML ブロックに直接書いた JavaScript が招く問題

WordPress の「カスタム HTML」ブロックに <script> タグを直書きする方法は、一見手軽だが制御が難しい。出力される位置がテーマやブロック配置に依存し、jQuery などのライブラリより前に実行されれば必ず失敗する。さらにインラインスクリプトは多くのキャッシュプラグインで最適化対象から外されたり、結合・遅延読み込みの対象にならず、ログアウト時だけ二重に不利な状況を生む。
HTML ブロック直書きスクリプトの3つの弱点
- 読み込み順序を制御できない(テーマの render 順に依存する)
- jQuery の依存関係を WordPress に伝えられない
- キャッシュ・圧縮プラグインがスクリプトとして認識しない場合がある
ログアウト時でも動くようにする正しい組み込み手順

原則は「JavaScript は HTML ブロックに直書きせず、WordPress の仕組み(wp_enqueue_script)で読み込む」ことだ。すでに直書きで動いているものを移行するには、以下の手順で進める。
STEP 1 既存の script タグを外部ファイルに移す
HTML ブロック内の <script>〜</script> 部分だけを抜き出し、子テーマのフォルダ内に testimonial-slider.js のような名前で保存する。<script> タグそのものは不要で、中身のコードだけを移す。HTML ブロックにはスライダーの構造(ul や div のマークアップ)だけを残す。
STEP 2 functions.php で安全に読み込む
子テーマの functions.php に以下のコードを追加する。管理画面ではなくフロントエンドだけに読み込ませるために wp_enqueue_scripts フックを使う。依存関係として jquery を指定すれば、WordPress 本体の jQuery が先に読み込まれてから実行される。
function my_testimonial_slider_script() {
wp_enqueue_script(
'testimonial-slider',
get_stylesheet_directory_uri() . '/testimonial-slider.js',
array('jquery'),
'1.0.0',
true
);
}
add_action('wp_enqueue_scripts', 'my_testimonial_slider_script');最後の引数 true はフッターで読み込む指定だ。スライダーの DOM 要素が本文中に存在する場合はフッター読み込みで問題ない。もしスライダーを本文より前に実行する必要があるなら false にしてヘッダーで読ませるが、多くのケースではフッターで十分だ。
STEP 3 $ の衝突を防ぐ
WordPress の jQuery は noConflict モードで動作しているため、$ がそのまま使えない環境がある。古いコードを流用している場合は $ is not a function エラーが起きやすい。回避策として、外部ファイル全体を即時実行関数で囲み、引数で $ を受け取る記法が安全だ。
(function($) {
$(document).ready(function() {
// ここにスライダーのコード
});
})(jQuery);STEP 4 キャッシュプラグインでスクリプトを除外する
ここまで対応しても直らない場合、キャッシュや最適化プラグインが原因の可能性が高い。ログアウト時はページキャッシュが有効になり、スクリプトの遅延読み込みや結合が適用される。自前の testimonial-slider.js をこれらの処理から除外する必要がある。
プラグインの設定画面で「スクリプトの除外」「遅延読み込みの除外」といった項目を探し、testimonial-slider(ハンドル名)または testimonial-slider.js(ファイル名の一部)を指定する。除外後は必ずキャッシュを全削除してからログアウト状態で確認する。
Elementor のフックやテーマのアクションフックを使った場合の注意点

テーマ付属のフック(GeneratePress の Element など)に HTML ブロックごと差し込む方法も考えられるが、根本的にはスクリプトの読み込み順序問題は同じだ。フックで出力する位置を変えても、jQuery より前に呼ばれるリスクは残る。フックを使う場合でも、スクリプト部分は wp_enqueue_script に任せ、フックにはマークアップだけを出力する形が堅実だ。
Elementor Pro の「カスタムコード」機能を使っているなら、その中に script タグを書くのではなく、同様に子テーマのファイルとして切り出してハンドル登録するほうが制御できる。どうしても直書きが必要なら、カスタムコードの「場所」設定を「本文の終了タグ直前」にし、さらにコード内で jQuery を明示的に使う($ を使わない)ことでエラーを減らせる。
よくある質問
コンソールに「$ is not defined」と出るがどう直せばいいか
jQuery が読み込まれる前に $ を使っているか、noConflict モードで $ が無効になっている。即時関数で (function($) { ... })(jQuery); とラップし、すべての $ をこのスコープ内に収めれば解決する。
functions.php を編集せずに直す方法はあるか
「WPCode」などのコードスニペット管理プラグインを使えば、管理画面から wp_enqueue_script のコードを登録できる。functions.php を直接触りたくない場合の現実的な代替手段だ。スニペットの実行場所を「フロントエンドのみ」に設定するのを忘れないようにする。
キャッシュを削除しても直らないのはなぜか
ブラウザキャッシュだけを消していて、サーバー側のページキャッシュや CDN キャッシュが残っているケースが多い。WordPress のキャッシュプラグインの「すべてのキャッシュを削除」を実行し、さらに CDN を使っている場合はその管理画面からもパージする。シークレットウィンドウで確認するとブラウザキャッシュの影響を除外できる。
スライダーのマークアップだけ残して script を外したら表示が消えた
新しく作った JS ファイルが正しく読み込まれていない。ブラウザの開発者ツールの「ネットワーク」タブで testimonial-slider.js が 200 番で返っているか確認する。404 ならパスが間違っている。読み込まれているのに動かない場合は、コンソールに別のエラーが出ていないか調べる。
この記事のポイント
- ログアウト時だけ JavaScript が動かない原因は、jQuery の依存切れとキャッシュ最適化の複合
- HTML ブロックへの script 直書きは読み込み順序を制御できず、根本対策にならない
- wp_enqueue_script で jQuery 依存を明示し、外部ファイルとして切り出すのが正攻法
- 即時関数で $ の衝突を防ぎ、キャッシュプラグインでは独自スクリプトを除外対象に追加する
- Elementor やテーマフックを使う場合も、スクリプトだけは enqueue に任せる設計が堅実

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

AI時代のキャッシュ設計を再考する——AIクローラーがCDNに与える影響と対策
CDN(コンテンツデリバリネットワーク)のキャッシュ設計が、AIクローラーの台頭によって根本的な見直しを迫られている。Cloudflareのデータによると、同社ネットワーク上のトラフィックの32%は自動化されたトラフィックが占める。検索エンジンクローラーや監視ツールに加え、近年はAIアシスタントが回答生成のためにWebから情報を取得するケースが増加している。
AIエージェントは人間とは異なるアクセスパターンを示す。高頻度の並列リクエスト、人気ページではなく長尾コンテンツへの集中的なアクセス、サイト全体の網羅的なスキャンなどが特徴だ。このような振る舞いは、従来の人間向けに最適化されたキャッシュアルゴリズムを無効化し、キャッシュミス率の上昇とオリジンサーバー負荷の増大を引き起こす。
サイト運営者はAIクローラーへの対応に迫られる。ブロックするか、サービスを提供するかの選択を迫られるが、両者のトラフィックパターンは大きく異なるため、既存のキャッシュアーキテクチャでは一方に最適化するしかない。本記事では、AIトラフィックがCDNキャッシュに与える影響を分析し、新しいキャッシュ設計の方向性を探る。
AIクローラーと人間のトラフィックの根本的な違い

AIクローラーのトラフィックは、人間のブラウジング行動と比較して3つの主要な特徴を持つ。高ユニークURL比率、コンテンツの多様性、クロールの非効率性だ。
高ユニークURL比率と長尾コンテンツへのアクセス
Common Crawlの公開データによると、大規模Webクロールでは90%以上のページがコンテンツ的にユニークだ。AIクローラーは特定のコンテンツタイプに特化する傾向があり、技術文書、ソースコード、メディアファイル、ブログ記事など、目的に応じて異なるコンテンツを対象とする。
人間のユーザーがトップページや人気記事に集中するのに対し、AIクローラーはサイトの奥深くまで探索する。Wikipediaの利用データは、かつて「長尾」とされていたほとんどアクセスされないページが、現在では頻繁にリクエストされるようになったことを示している。これはCDNキャッシュ内のコンテンツ人気度分布そのものを変化させている。
クロールの非効率性と反復ループ
AIクローラーは必ずしも最適なクロールパスをたどらない。人気のあるAIクローラーからのフェッチのかなりの割合が404エラーやリダイレクトで終わる。これはURL処理の不備によることが多い。また、ブラウザ側のキャッシュやセッション管理を人間のユーザーと同じように利用しない。
AIエージェントは検索結果を改良するために反復ループを行うことがある。これはRAG(Retrieval-Augmented Generation)における一般的なパターンだ。この反復ループは、エージェントの精度を高める一方で、一貫して高いユニークアクセス比率(70%から100%)を維持する。つまり、各ループで以前に見たページを再訪するのではなく、常に新しいユニークなコンテンツを取得し続ける。
キャッシュへの直接的な影響
長尾アセットへのこのような反復アクセスは、人間のトラフィックが依存するキャッシュをかき回す。既存のプリフェッチや従来のキャッシュ無効化戦略は、クローラートラフィックの量が増加するにつれて効果が低下する。Cloudflareの単一ノードにおけるキャッシュヒット率は、AIクローラーを含む場合と含まない場合で明確な差が見られる。ヒット率の低下は、LRU(Least Recently Used)アルゴリズムがAIクローラーの反復スキャン行動に対処できていないことを示唆している。
実例から見るAIクローラーのインパクト

AIボットトラフィックの急増は、実際のWebサービスに深刻な影響を与えている。大規模サイトにおける影響と対応策は以下の通りだ。
Wikipedia:マルチメディア帯域幅の50%急増
モデル訓練のための画像一括スクレイピングにより、マルチメディア帯域幅使用量が50%急増した。Wikimediaは最終的にクローラートラフィックをブロックする対応を取った。
SourceHutとRead the Docs:サービス不安定化
ソースコードリポジトリをスクレイピングするLLMクローラーにより、サービス不安定化と速度低下が発生。Read the Docsでは、AIクローラーが大きなファイルを1日に数百回ダウンロードし、帯域幅の大幅な増加を引き起こした。両サービスとも一時的にクローラートラフィックをブロックし、IPベースのレート制限を実施した。
FedoraとDiaspora:人間ユーザーへの影響
Fedoraはパッケージミラーを再帰的にクロールするAIスクレイパーにより、人間ユーザーに対する応答速度が低下。Diasporaソーシャルネットワークは、robots.txtを尊重しない積極的なスクレイピングにより、応答速度の低下とダウンタイムを経験した。両者とも既知のボットソースからのトラフィックを地理的にブロックするなどの対応を取った。
これらの事例が示すのは、AIクローラーを単純にブロックするだけでは根本的な解決にならないということだ。よりスマートなキャッシュアーキテクチャがあれば、サイト運営者はAIクローラーにサービスを提供しつつ、人間ユーザーの応答時間を維持できる。
AI時代に向けたキャッシュ設計の新たな方向性

AIトラフィックの特性を考慮した新しいキャッシュ設計が必要とされている。主なアプローチは2つある。AIを意識したキャッシュアルゴリズムによるトラフィックフィルタリングと、AIクローラートラフィック専用の新しいキャッシュ層の追加だ。
ワークロード対応型キャッシュアルゴリズム
現在広く使用されているLRU(Least Recently Used)アルゴリズムは、汎用状況においてシンプルさ、低オーバーヘッド、有効性のバランスが取れている。しかし、人間とAIボットの混合トラフィックに対しては、別のキャッシュ置換アルゴリズムの選択が有効かもしれない。
初期実験では、SEIVEやS3FIFOといったアルゴリズムを使用することで、AIの干渉の有無にかかわらず、人間トラフィックが同じヒット率を達成できる可能性が示されている。さらに、ワークロードを直接意識した機械学習ベースのキャッシュアルゴリズムを開発し、リアルタイムでキャッシュ応答をカスタマイズする実験も進められている。これにより、より高速でコスト効率の高いキャッシュが実現できる。
トラフィック種別に応じた階層化キャッシュアーキテクチャ
長期的には、AIトラフィック専用の別個のキャッシュ層が最善の道となる。人間とAIのトラフィックをネットワークの異なる層に配置された別個の階層にルーティングするキャッシュアーキテクチャが考えられる。
人間トラフィックは、応答性とキャッシュヒット率を優先するCDN PoP(Point of Presence)のエッジキャッシュから引き続きサービスされる。一方、AIトラフィックのキャッシュ処理はタスクタイプによって変えることができる。
RAGやリアルタイム要約のようなライブアプリケーションを支えるAIクローラーでは、レイテンシが重要だ。これらのリクエストは、より大きな容量と適度な応答時間のバランスが取れたキャッシュにルーティングされるべきである。これらのキャッシュは鮮度を保ちつつも、人間向けキャッシュよりもわずかに高いアクセスレイテンシを許容できる。
訓練セットの構築や大規模コンテンツ収集ジョブに使用されるAIクローラーは、かなり高いレイテンシを許容し、時間的制約がない。これらのワークロードは、到達までに時間がかかる深いキャッシュ階層(オリジン側のSSDキャッシュなど)からサービスできる。あるいは、キューベースのアドミッションやレートリミッターを使用して遅延させ、バックエンドの過負荷を防ぐことも可能だ。これにより、インフラに負荷がかかっている場合にバルクスクレイピングを延期する機会も生まれる。
この記事のポイント
- AIクローラーは全ネットワークトラフィックの約3分の1を占め、そのアクセスパターンは人間のブラウジング行動と根本的に異なる。
- 高ユニークURL比率、長尾コンテンツへの集中アクセス、反復ループによるキャッシュチャーンが、従来のLRUキャッシュアルゴリズムの効果を低下させている。
- WikipediaやFedoraなどの大規模サイトでは、AIクローラーによる帯域幅急増やサービス不安定化が実際に発生し、多くのサイトがクローラーブロックに頼らざるを得なくなっている。
- 根本的な解決策として、SEIVEやS3FIFOなどの新しいキャッシュアルゴリズムの採用と、AIトラフィック専用の階層化キャッシュアーキテクチャの構築が検討されている。
- 今後のCDN設計では、人間トラフィックとAIトラフィックを分離し、それぞれの特性に最適化したキャッシュ戦略を適用することが重要になる。

・ 複数業界における17年間のデジタルビジネス開発経験
・ ウェブサイト開発のためのHTML、PHP、CSS、JavaScript等の実用的知識
・ 15ヶ国語対応の多言語SaaSの開発経験
・ 17年間にも及ぶ、Eコマース長期運営経験
・ 幅広い業界でのSEO最適化の豊富な経験

Seraphinite Acceleratorの脆弱性、6万サイトに影響 認証済みユーザーが内部データを取得可能
WordPressの高速化プラグイン「Seraphinite Accelerator」に深刻なセキュリティ脆弱性が発見された。この脆弱性により、最低限の権限を持つ認証済みユーザーがサイトの内部データを取得できる状態だった。
影響を受けるのはバージョン2.28.14までの全バージョンで、インストールサイト数は6万以上に及ぶ。開発元はバージョン2.28.15で修正を実施した。
この問題は、パフォーマンス向上を目的としたプラグインが、逆にセキュリティリスクを生み出すという構造的な課題を示している。
脆弱性の概要と影響範囲

2026年3月4日、セキュリティ企業のWordfenceがSeraphinite Acceleratorプラグインに関する2件の脆弱性を公表した。これらの脆弱性は「CVE-2026-XXXXX」および「CVE-2026-XXXXY」として追跡されている。
認証済みユーザーによる情報取得
1つ目の脆弱性は情報漏洩に関わる。プラグインが提供するAPIエンドポイント「seraph_accel_api」に、権限チェックの不備が存在した。
このエンドポイントを通じて「GetData」関数を呼び出すと、内部の「OnAdminApi_GetData()」関数が実行される。本来、この関数は管理者のみがアクセス可能なシステム情報を返すものだ。
しかし、関数内に適切な権限チェック(capability check)が実装されていなかった。その結果、購読者レベル(Subscriber)以上の権限を持つすべての認証済みユーザーが、このAPIを呼び出せた。
取得可能な内部データの具体例
攻撃者がこの脆弱性を悪用した場合、以下のような運用上の機密情報を取得できた。
- キャッシュの状態情報
- スケジュールされたタスクの詳細
- 外部データベースの状態
これらの情報は、サイトの内部構造やプラグインの動作状況を外部から可視化するものだ。直接的な管理者権限の奪取にはつながらないが、サイトのインフラを調査する足がかりとなる。
第二の脆弱性:ログの無許可消去
2つ目の脆弱性も同様の権限チェック不備に起因する。今度は「LogClear」関数に問題があった。
攻撃者はこの関数を呼び出すことで、プラグインのデバッグログや操作ログを消去できた。ログの改ざんや消去は、攻撃の痕跡を隠蔽するために利用される。
Seraphinite Acceleratorの役割とリスクの逆説

Seraphinite AcceleratorはWordPressサイトの表示速度を向上させるパフォーマンスプラグインだ。主な機能はページのキャッシュ生成にある。
サーバーは訪問者が来るたびにページを生成する必要がなくなる。これによりサーバー負荷が軽減され、ページ読み込みが高速化する。プラグインはGZip、Deflate、Brotliといった複数の圧縮形式をサポートする。ブラウザキャッシュの有効化や、デバイス・環境ごとのキャッシュ分離にも対応している。
パフォーマンスとセキュリティのトレードオフ
今回の事例は、パフォーマンス最適化ツールがセキュリティホールになり得ることを示している。キャッシュプラグインはサーバーとクライアントの間に立つ。高度な最適化処理を行うため、システムの深部にアクセスする権限が必要となる。
この特権的なアクセス権を、適切なセキュリティ境界(セキュリティバウンダリ)で保護しなければならない。Seraphinite Acceleratorの場合、管理機能を提供するAPIエンドポイントの実装に不備があった。
「管理者API」の誤った実装
脆弱性の核心は「OnAdminApi_GetData()」という関数名が示す通りだ。この関数は「管理者向けAPI」の一部として設計された。関数名には「Admin」が含まれている。
しかし、実際の実装では管理者権限の有無を確認していなかった。WordPressのプラグイン開発において、管理機能には通常「manage_options」という権限(キャパビリティ)が必要だ。このチェックが欠落していた。
筆者の分析では、これは単純な実装ミスというより、権限モデルの設計段階での見落としの可能性が高い。パフォーマンス系プラグインは、しばしば高度なシステム操作と一般ユーザー向け機能の境界が曖昧になりがちだ。
攻撃シナリオと実際のリスク

この脆弱性を悪用するには、攻撃者はまず対象サイトに「購読者」アカウントを登録する必要がある。多くのWordPressサイトでは、コメント投稿やニュースレター登録のためにユーザー登録を開放している。
低権限アカウントの取得方法
攻撃者は以下のような方法で購読者アカウントを取得する。
- 公開されたユーザー登録フォームを利用する
- ソーシャルエンジニアリングで既存ユーザーの資格情報を窃取する
- 他の脆弱性やパスワード漏洩を利用する
一度購読者権限を取得すれば、攻撃者は特別なツールや高度な技術なしに脆弱性を悪用できる。通常のWebリクエストを送信するだけで済む。
情報収集からさらなる攻撃へ
取得した内部データは、より深刻な攻撃の前段階として利用される。キャッシュの状態やスケジュールタスクの情報から、サイトの運用パターンや使用している技術スタックを推測できる。
例えば、特定のキャッシュシステムの既知の脆弱性を探す材料となる。外部データベースの状態が分かれば、データベースに対する攻撃を計画する際の情報となる。
ログ消去機能の悪用は、防御側の可視性を奪う。攻撃者が他の方法でサイトに侵入した後、痕跡を消すためにこの機能を使う可能性がある。
開発元の対応と修正内容

脆弱性の報告を受け、Seraphinite Acceleratorの開発チームは速やかに対応した。バージョン2.28.15で修正パッチをリリースしている。
修正の技術的詳細
修正内容は明確だ。問題のあった「OnAdminApi_GetData()」関数および「LogClear」関連関数に、適切な権限チェックを追加した。
具体的には、関数の実行前に現在のユーザーが「manage_options」権限を持っているか確認するコードを追加した。この権限はWordPressにおいて、管理画面の設定を変更できる管理者ユーザーに与えられる。
変更履歴(チェンジログ)には、「LogClearおよびGetData API関数が、manage_options権限を持たないユーザーによって呼び出される可能性があった」と記載されている。修正により、これらの関数へのアクセスは管理者のみに制限された。
自動更新の有無と適用状況
WordPressのプラグインは、マイナーアップデートについては自動更新機能が働く場合がある。しかし、セキュリティアップデートが自動的に適用されるかは、サイトの設定に依存する。
多くのレンタルサーバーや管理サービスは、セキュリティ更新を自動適用する設定を推奨している。とはいえ、すべてのサイトが即座に更新されるわけではない。6万サイトという影響範囲を考えると、未適用のサイトが相当数残っている可能性がある。
サイト運営者が取るべき対策

Seraphinite Acceleratorを使用しているサイト運営者は、直ちに行動する必要がある。以下の手順に従って対応すべきだ。
緊急措置:プラグインの更新
まず、プラグインをバージョン2.28.15以降に更新する。WordPress管理画面の「プラグイン」セクションにアクセスし、Seraphinite Acceleratorの横に「更新あり」と表示されていないか確認する。
更新が利用可能な場合は、速やかに実行する。更新後はサイトの表示や機能に問題がないか確認する。パフォーマンスプラグインの更新は、キャッシュの再構築を伴う場合がある。
更新ができない場合の暫定対策
何らかの理由で直ちに更新できない場合、以下の暫定対策を検討する。
- プラグインを一時的に無効化する
- ユーザー登録機能を一時的に停止する
- Webアプリケーションファイアウォール(WAF)で該当APIへのリクエストをブロックする
プラグイン無効化の影響
Seraphinite Acceleratorを無効化すると、キャッシュ機能が停止する。サイトの表示速度が一時的に低下する可能性がある。特にトラフィックの多いサイトではサーバー負荷が増加する。
代替として、他のキャッシュプラグインを一時導入する方法もある。ただし、新たなプラグインの設定や互換性の問題が生じるリスクは承知すべきだ。
長期的なセキュリティ体制の見直し
今回の事例を機に、サイト全体のセキュリティ体制を見直す価値がある。
- 使用プラグインの定期的な監査
- 最小権限の原則に基づくユーザー権限設定
- セキュリティプラグインの導入と適切な設定
- ログの定期的な監視とバックアップ
パフォーマンスプラグインは、その性質上、システムへの深いアクセス権を要求する。導入前に開発元のセキュリティ対応実績を調べる。アクティブインストール数が多いからといって、安全が保証されるわけではない。
パフォーマンスプラグイン選定の新たな視点

Seraphinite Acceleratorの脆弱性は、パフォーマンスツールの選定基準にセキュリティ評価を加える必要性を浮き彫りにした。
コードの質とセキュリティ文化
プラグインを選ぶ際、機能や速度向上効果だけで判断すべきではない。開発チームのセキュリティへの取り組みを評価する材料を探す。
定期的な更新が行われているか。セキュリティアドバイザリに対して迅速に対応しているか。コードが適切に構造化され、権限チェックが一貫して実装されているか。これらの点は、プラグインの長期にわたる信頼性を示す指標となる。
代替手段の検討
サイトの高速化は、単一のプラグインに依存せず、多層的なアプローチで達成できる。サーバーレベルのキャッシュ、CDN(コンテンツデリバリネットワーク)の利用、画像最適化など、リスクを分散させる方法がある。
例えば、信頼性の高い共用サーバーやクラウドサービスでは、サーバー側でキャッシュ機能を提供している場合が多い。これらの機能を最大限活用することで、プラグインへの依存度を下げられる。
この記事のポイント
- Seraphinite Acceleratorの脆弱性は、認証済みユーザーが内部データを取得可能にするものだ。
- 影響を受けるのはバージョン2.28.14までで、6万以上のサイトが該当する。
- 脆弱性の根本原因は、API関数における権限チェックの欠如にある。
- サイト運営者はプラグインをバージョン2.28.15以降に即時更新すべきだ。
- パフォーマンスプラグイン選定には、セキュリティ対応実績の評価が不可欠である。
出典
- Search Engine Journal “Seraphinite Accelerator WordPress Plugin Vulnerabilities Affect 60K Sites” (2026年3月4日)
- Wordfence Threat Intelligence “Seraphinite Accelerator 2.28.14 – Authenticated (Subscriber+) Exposure of Sensitive Information” (2026年3月)
- Wordfence Threat Intelligence “Seraphinite Accelerator 2.28.14 – Missing Authorization to Authenticated (Subscriber+) Log Clearing” (2026年3月)

・ 複数業界における17年間のデジタルビジネス開発経験
・ ウェブサイト開発のためのHTML、PHP、CSS、JavaScript等の実用的知識
・ 15ヶ国語対応の多言語SaaSの開発経験
・ 17年間にも及ぶ、Eコマース長期運営経験
・ 幅広い業界でのSEO最適化の豊富な経験
