AIOSEO で投稿のメタディスクリプションが保存できず「投稿の抜粋」に戻ってしまう問題の原因と解決方法

AIOSEO で投稿のメタディスクリプションが保存できず「投稿の抜粋」に戻ってしまう問題の原因と解決方法

WordPress + AIOSEO(All in One SEO)でメタディスクリプションを手動入力しても、保存後に デフォルト設定の「投稿の抜粋」に戻ってしまう という問題に遭遇しました。

原因はかなり意外な場所にあり、最終的にロリポップサーバーの WAF(Web Application Firewall)の誤検知が原因だと判明しました。同じ症状で困っている方の参考になればと思い、切り分けから解決までの過程を記事にまとめます。

発生環境

  • WordPress: 投稿型サイト
  • AIOSEO: バージョン 4.9.7.2
  • テーマ: LION BLOG
  • サーバー: ロリポップ!レンタルサーバー
  • DB: MySQL(接頭辞 wp4_

発生した症状

AIOSEO の投稿編集画面で メタディスクリプション欄に手動で文章を入力 → 投稿を更新 すると、保存後にフォームの内容が消えて、デフォルトで設定してある「投稿の抜粋」のスマートタグに戻ってしまう。

ややこしい挙動として:

  • すべての記事ではなく、一部の記事だけで発生する
  • データベースの wp4_aioseo_posts テーブルを確認しても、入力した文字列が description カラムに 書き込まれていない
  • 直接 SQL で UPDATE すると問題なく反映される
  • 「説明の自動生成」を一度 ON にして OFF に戻した後あたりから発生し始めた感覚

つまり「DB側は正常、フォームから保存する経路だけ壊れている」状態でした。

切り分けの過程

1. AIOSEO のキャッシュテーブルを疑う

最初に疑ったのは AIOSEO 4.9.7 で発生した キャッシュテーブル破損の既知不具合 です。公式 Changelog に以下の記載があります。

Cache table on some sites was left in a corrupted state after the 4.9.7 update due to a race condition during the migration, causing cache writes to silently overwrite unrelated entries.

「キャッシュ書き込みが無関係なエントリを上書きする」という挙動なら、症状と一致します。

phpMyAdmin で確認:

SHOW TABLE STATUS LIKE 'wp4_aioseo_cache';
SELECT COUNT(*) FROM wp4_aioseo_cache;
SHOW INDEX FROM wp4_aioseo_cache;

結果はテーブル正常、インデックスも PRIMARY / ndx_aioseo_cache_name / ndx_aioseo_cache_expiration が揃っていて問題なし。

念のため WPCode プラグインでキャッシュテーブルを再作成するスニペットも実行してみました。

add_action( 'init', function() {
    if ( function_exists( 'aioseo' ) ) {
        aioseo()->preUpdates->createCacheTable();
    }
});

実行後も症状は変わらず。キャッシュテーブルの破損は原因ではない ことが判明。

2. ブラウザの開発者ツールでリクエストを確認

ここで方向転換し、ブラウザの開発者ツール(F12)→ Network タブで保存ボタン押下時の通信を確認しました。

すると、以下のリクエストで 403 Forbidden が返ってきていることを発見:

Request URL: https://example.com/wp-admin/post.php?post=96698&action=edit&meta-box-loader=1&meta-box-loader-nonce=xxxxxxxxxx&_locale=user
Request Method: POST
Status Code: 403 Forbidden

meta-box-loader=1 は WordPress のブロックエディタが メタボックスのデータを保存する際に使う専用エンドポイント です。AIOSEO の入力欄もこの経路で保存されます。

つまり投稿本体は REST API で保存されているのに、AIOSEO 関連のデータだけ 403 で弾かれていたわけです。「一部の記事だけ問題が出る」のも、送信内容によって 403 になったりならなかったり していたのが理由でした。

3. レスポンスボディを確認 → ロリポップの 403 ページが返ってきていた

403 リクエストの Response タブを確認すると、以下のような HTML が返ってきていました:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>403 Error - Forbidden</title>
  ...
</head>
<body>
  <div class="container">
    ...
    <h1 class="message">403 Error</h1>
    <p>現在、このページへのアクセスは禁止されています。<br>
    詳しくは以下のページをご確認ください。</p>
    <a href="https://support.lolipop.jp/hc/ja/articles/360049132833">403ERRORというエラーが発生します</a>
  </div>
</body>
</html>

これは ロリポップが返している 403 エラーページ です。つまり、WordPress やプラグインの問題ではなく、サーバー側でリクエストがブロックされていた ということ。

リンク先のロリポップサポートページを確認すると、原因はほぼ確実に WAF(Web Application Firewall)の誤検知 によるものでした。

4. ここまでで除外できた要因

ちなみに、ここに到達するまでに以下を1つずつ試して除外しています:

  • ✅ AIOSEO のキャッシュテーブル再作成
  • ✅ SiteGuard WP Plugin の無効化
  • .htaccess の確認(WordPress 標準ルールのみで問題なし)
  • ✅ 同サーバーの他 WordPress サイトでは発生しないことを確認

解決方法

ロリポップの WAF を一時的に無効化

ロリポップのユーザー専用ページから WAF を無効化します。

ユーザー専用ページ → セキュリティ → WAF設定

該当ドメインの WAF を「無効」に切り替え。

注意点:

  • 設定の反映に 5〜10分かかる ことがあります
  • ドメインごとに設定されているので、複数ドメインを契約している場合は対象ドメインを間違えないように
  • 切り替え直後にテストしても変わらず、しばらくしてから保存できるようになる

WAF を無効にした状態で、問題の記事のメタディスクリプションを手動入力 → 更新したところ、無事に保存され、wp4_aioseo_posts テーブルにもデータが書き込まれました。

検出されたシグネチャの確認

WAF を無効にしたまま運用するのはセキュリティ上望ましくないので、ロリポップの WAF ログで実際にどのシグネチャに引っかかっていたか確認します。

ユーザー専用ページ → セキュリティ → WAF設定 → ログ参照

確認した結果、すべて SQLインジェクション検出系のシグネチャ が引っかかっていました。

検出されたシグネチャURL
sqlinj-9/wp-admin/post.php?...&meta-box-loader=1...
sqlinj-10/wp-admin/post.php?...&meta-box-loader=1...
sqlinj-20/wp-admin/post.php?...&meta-box-loader=1...
sqlinj-21/wp-admin/post.php?...&meta-box-loader=1...

技術系の記事は本文中に SELECTUPDATEUNION などの SQL キーワードや、シングルクォート・コメント記号(--/* */)などが頻出します。これらが SQL インジェクション攻撃の試行パターンと誤検知され、保存リクエストが弾かれていたわけです。

恒久対応:シグネチャ単位での除外設定

WAF をずっと無効にしておくのはセキュリティ的に良くないので、検出されたシグネチャだけを除外する のが正攻法です。

.htaccess の WordPress ブロックよりも前に、以下を追記します。

<IfModule mod_siteguard.c>
    SiteGuard_User_ExcludeSig sqlinj-9
    SiteGuard_User_ExcludeSig sqlinj-10
    SiteGuard_User_ExcludeSig sqlinj-20
    SiteGuard_User_ExcludeSig sqlinj-21
</IfModule>

追記後、WAF を「有効」に戻して再度保存をテストし、403 が出ないことを確認します。これでそのシグネチャだけが除外され、それ以外の WAF 機能は維持されます。

なお、シグネチャ ID は WAF のアップデートで増えることがあるため、もし同じ種類のエラーが別の番号で再発した場合は、ログを見て該当する番号を追加してください。

まとめ

AIOSEO のメタディスクリプションが保存できず「投稿の抜粋」に戻ってしまう問題の原因と解決の流れをまとめると:

  1. 症状: 手動入力したメタディスクリプションが保存されず、DB にも書き込まれない(一部の記事のみ)
  2. 原因: ロリポップサーバーの WAF が、保存リクエストの POST ボディに含まれる SQL キーワードや記号を SQLインジェクション攻撃と誤検知し、/wp-admin/post.php?meta-box-loader=1 への POST を 403 でブロックしていた(検出シグネチャ: sqlinj-9 / sqlinj-10 / sqlinj-20 / sqlinj-21
  3. 解決: 該当シグネチャを .htaccess で除外設定し、WAF は有効のまま維持

切り分けで重要だったポイント:

  • ブラウザの 開発者ツール(Network タブ) で実際のリクエストとレスポンスを確認すること
  • 403 のレスポンスボディを見て、誰が(WordPress / プラグイン / サーバー)返しているのか特定すること
  • 一部の記事だけ問題が起きる」場合、コンテンツ依存のセキュリティ機能(WAF など)を疑う価値があること

同じ症状で困っている方は、AIOSEO 本体やプラグイン同士の競合を疑う前に、サーバーの WAF 設定403 のレスポンス内容 を確認してみることをおすすめします。

参考サイト