【実体験】WordPressがSEOスパム被害に。Googlebotにだけ偽通販ページが表示された原因調査と復旧まで

技術系

WordPressで運営しているブログをGoogle Search Consoleで確認したところ、まったく投稿した覚えのないフランス語の通販ページが、自分のドメイン配下に大量に現れていました。

ところが、該当URLを普通に開くと「404 Not Found」。ページは存在しないように見えます。それなのに、検索エンジン向けのアクセスでは偽の通販ページが返されるという不可解な状態でした。

今回は、実際に遭遇したSEOスパム(検索結果を悪用する不正ページ)とクローキング(アクセス元によって表示内容を変える手法)の症状、WordPress・サーバー内で行った切り分け、そして最終的にWordPressリカバリーで改善した経緯をまとめます。

この記事の結論:調査時には、通常のアクセスが404なのに、Googlebotを名乗るUser-AgentではHTTP 200と偽通販ページのHTMLが返る状態を確認しました。WordPressのファイルやデータベースを調べましたが、不正コードの設置場所までは特定できませんでした。その後、WordPressリカバリーを実施したところ、確認した不正URLではGooglebotを指定しても404が返るようになりました。

※本記事は個人サイトでの実例です。今回の検証ではUser-Agentを「Googlebot」に変更していますが、Googleの正規クローラーのIPアドレスからアクセスしたわけではありません。また、リカバリーによる症状改善と、侵入経路の特定・完全な安全性の証明は別です。

1. WordPressサイトに身に覚えのない通販ページが大量発生

異変に気づいたきっかけは、Google Search Consoleでした。自分で作成した記事とは無関係のURLが、ryotravel.com 配下に多数見つかったのです。

例えば、次のようなURLです。(URLを一部サニタイズ)

https;//ryotravel.com/Bois-Fairway-TaylorMade-Stealth-Plus-15-Gaucher-Sans-793443/
https;//ryotravel.com/3-7-M-Pour-Cheval-quitation-Fabrication-Fran-aise-Neuve-1123037/
https;//ryotravel.com/Hamac-Double-KLYMIT-400-Lbs-2-Places-Rouge-Nylon-Pour-938804/

いずれも、私が作成したページではありません。URLにはゴルフ用品やアウトドア用品などの商品名らしき単語が含まれ、フランス語の通販ページを思わせる構造になっていました。

通常のブラウザでは404になる

不審なURLを開いても、普通のアクセスでは404エラーが返ってきます。これだけを見ると、すでにページが削除されたようにも思えます。

しかし、Search Consoleに見慣れないURLが現れている以上、404という結果だけで問題が解決したとは判断できません。検索エンジンと一般の訪問者に別の内容を返している可能性を考え、アクセス条件を変えて検証しました。

2. Googlebotを指定すると偽通販ページが返ることを確認

今回の調査で最も重要だったのが、HTTPリクエストのUser-Agentを変更した比較です。

User-Agentは、ブラウザやクローラーが自分の種類をサーバーに伝えるための情報です。通常のブラウザを名乗る場合と、Googlebotを名乗る場合でレスポンスが変わるか、curl で調べました。

SSHからcurlで比較する

XserverにSSH接続し、以下のようなコマンドを実行します。

URL="https://ryotravel.com/Bois-Fairway-TaylorMade-Stealth-Plus-15-Gaucher-Sans-793443/"

for UA in "Mozilla/5.0" "Googlebot"; do
  echo "===== $UA ====="
  curl -sS -L \
    -A "$UA" \
    -o /tmp/seo_check.html \
    -w "HTTP: %{http_code}\nSIZE: %{size_download}\n" \
    "$URL"

  grep -ioE 'cdiscount\.com|kreel-referer' \
    /tmp/seo_check.html | sort | uniq -c
done

-A でUser-Agentを指定し、-w でHTTPステータスコードと受信サイズを表示します。さらに、返されたHTMLから偽通販ページに関連する文字列を検索しています。

調査時の結果

当初、対象URLでは次のような差が確認できました。

確認項目通常のUser-AgentGooglebotを名乗るUser-Agent
HTTPステータス404200
受信HTMLサイズ約618KB約367KB
ページ内容404ページフランス語の偽通販ページ
cdiscount.com など不正ページの特徴を確認できず不正HTML内で確認

つまり、通常のアクセスではページが存在しないように見せながら、Googlebotを名乗るアクセスには別のHTMLを返していたのです。

このようにアクセス元によってコンテンツを出し分ける挙動は、一般に「クローキング」と呼ばれます。検索エンジンにだけ不正ページを見せて検索結果へ露出させるSEOスパムの手法と整合する症状でした。

返されたHTMLの特徴

取得した不正HTMLには、次のような特徴がありました。

  • <html lang="fr"> と指定されたフランス語ページ
  • 商品名を含むtitleタグ
  • 自分のドメイン内の不正URLを指定したcanonicalタグ
  • index,follow を指定したrobotsメタタグ
  • cdiscount.com 関連のJavaScriptやCSSへの参照
  • kreel-referer というCookieや、リファラーに関わるJavaScript処理

特に気になったのは、偽通販ページの正規URL(canonical)が自分のドメインを指していたことです。単なる外部サイトへのリンクではなく、自分のサイト配下のページとして検索エンジンに認識させようとしているように見えました。

ただし、このHTMLはあくまでサーバーから返ってきた結果です。HTMLを見つけただけでは、不正ページを生成・配信しているPHPファイルや侵入経路まで特定できません。

3. WordPressのファイルとデータベースを切り分け

Googlebot向けに別のHTMLが返ることが分かったため、次は「どこでレスポンスが切り替えられているのか」を調べました。

調査対象は、Xserver上のWordPressファイル、プラグイン、キャッシュ、データベースです。

.htaccessとPHP設定を確認

最初に疑ったのは、.htaccess に仕込まれたリダイレクトや条件分岐です。User-Agentに応じて別の処理を実行する設定がないか確認しました。

確認した範囲では、WordPressの標準的なリライトルールが中心で、今回の偽通販ページを直接説明できる不審な記述は見つかりませんでした。

また、.user.ini の auto_prepend_file と auto_append_file も確認しましたが、いずれも不正なPHPファイルの読み込み先は設定されていませんでした。

uploads・テーマ・プラグインを確認

次に、WordPress内のファイルを調べました。主に確認したのは次の場所です。

public_html/.htaccess
public_html/wp-config.php
public_html/wp-content/uploads/
public_html/wp-content/themes/
public_html/wp-content/plugins/
public_html/wp-content/mu-plugins/
public_html/wp-content/cache/

uploads 内に不審なPHPファイルがないか確認し、テーマやプラグイン内では cdiscount.com や kreel-referer といった特徴的な文字列を検索しました。

例えば、調査の考え方は次のようなものです。

# WordPressの設置ディレクトリで実行する例
# ※実際のパスは環境に合わせて変更
cd ~/ryotravel.com/public_html

grep -RniE 'cdiscount\.com|kreel-referer|Bois-Fairway' \
  --include='*.php' --include='*.html' wp-content

※上記は再現用のコマンド例です。設置ディレクトリはサーバー構成によって異なります。

今回確認した範囲では、検索した特徴的な文字列に一致する不正コードは見つかりませんでした。また、mu-plugins 内にも該当するファイルは確認できませんでした。

キャッシュも確認したが、原因は特定できず

サイトではAutoptimizeを使用していたため、wp-content/cache/autoptimize 内のキャッシュファイルも調査しました。

さらに、autoptimize_404_handler.php というファイルも確認しましたが、これはAutoptimizeのCSS・JavaScript配信に関連する処理であり、調査時点では今回の偽通販ページの生成元と判断できる証拠はありませんでした。

キャッシュに不正ページが残っているだけなのか、それとも別の仕組みで動的に生成されているのかも疑いましたが、決定的な原因は見つかりませんでした。

データベースも検索

phpMyAdminから、WordPressの投稿データを格納する wp_posts や、各種設定を格納する wp_options も調べました。

偽通販ページの商品名や特徴的な文字列を検索したものの、調査した範囲では不正ページの生成元となるデータは確認できませんでした。

なお、WordPressのテーブル接頭辞は環境によって異なります。wp_posts や wp_options という名前は一例です。

切り分けの結果

.htaccess、PHP設定、テーマ・プラグイン、キャッシュ、データベースを確認しましたが、不正コードの設置場所や侵入経路の特定には至りませんでした。

ファイル内に検索文字列が存在しないからといって、感染していないとは限りません。文字列が難読化されている場合や、別の場所・別の条件で処理されている場合もあります。

原因不明のまま闇雲にファイルを削除すると、正常なWordPressまで壊してしまうおそれがあります。そこで、サイトの復旧を優先することにしました。

4. 最終的にWordPressリカバリーを実施して改善

複数の切り分けを行っても原因となるコードを特定できなかったため、最終的にWordPressリカバリーを実施しました。

その結果、少なくとも今回追跡していた不正URLでは、以前のようなGooglebot向けの偽通販ページが返らなくなりました。

ここで重要なのは、「リカバリーを実施した結果、症状が改善した」という事実と、「原因を完全に突き止めた」という話を混同しないことです。

今回の調査では、どのファイルが改ざんされていたのか、どの脆弱性や認証情報が侵入に使われたのかまでは確認できていません。そのため、リカバリーがどの不正処理を取り除いたのかを断定することはできません。

参考にした手順は以下です。
https://www.xserver.ne.jp/manual/man_server_wprecovery.php

同様の被害で復旧作業を行う場合は、作業前にサイトとデータベースのバックアップを取得し、復元対象・復元日時・プラグインの状態などを記録しておくことをおすすめします。後から原因を追跡する際にも役立ちます。

5. リカバリー後に同じ不正URLで再検証

リカバリー後は、問題が発生していたURLをそのまま使い、同じ条件で再検証しました。

対象URLの例はこちらです。

https://ryotravel.com/Hamac-Double-KLYMIT-400-Lbs-2-Places-Rouge-Nylon-Pour-938804/

確認には、調査時と同様に curl を使用しました。

URL="https://ryotravel.com/Hamac-Double-KLYMIT-400-Lbs-2-Places-Rouge-Nylon-Pour-938804/"

for UA in "Mozilla/5.0" "Googlebot"; do
  echo "===== $UA ====="
  curl -sS -L \
    -A "$UA" \
    -o /tmp/seo_check.html \
    -w "HTTP: %{http_code}\nSIZE: %{size_download}\n" \
    "$URL"

  grep -ioE 'cdiscount\.com|kreel-referer|KLYMIT' \
    /tmp/seo_check.html | sort | uniq -c
done

再検証の結果

2026年10月25日に確認した結果は次のとおりです。

===== Mozilla/5.0 =====
HTTP: 404
SIZE: 617479
===== Googlebot =====
HTTP: 404
SIZE: 617479

どちらのUser-Agentでも HTTP 404 となり、受信サイズも一致しました。検索対象にした cdiscount.com、kreel-referer、KLYMIT の文字列も検出されませんでした。

また、別の不正URL(TaylorMadeの商品名を含むURL)でも、通常アクセスとGooglebotの両方で404となる結果を確認しています。

確認内容不正配信を確認した時点リカバリー後の確認
通常アクセス404404
Googlebotを名乗るアクセス200404
Googlebot向けの偽通販HTML返された確認したURLでは返されず

この結果から、少なくとも検証したURLについては、以前のクローキング挙動が再現しなくなったと判断しました。

ただし、すべての不正URLやアクセス条件を網羅したわけではありません。検索エンジンのインデックスからURLが消えるまでには時間がかかる場合もあります。Search ConsoleでのURL検査や、サーバーログの確認を継続することが重要です。

6. まとめ:SEOスパム被害から学んだこと

今回のWordPressトラブルで最も厄介だったのは、普通にページを開いただけでは問題が見えなかったことです。

不審URLが404を返していても、Googlebotを名乗るアクセスでは偽通販ページが返っていました。検索結果に不審なURLが現れたときは、通常のブラウザで確認するだけでなく、User-Agentを変更したHTTPレスポンスの比較が有効だと実感しました。

今回の調査を振り返ると、重要なポイントは次の4つです。

  1. Search Consoleで身に覚えのないURLを見つけたら放置しない。 自サイトのドメインがSEOスパムに悪用されている可能性があります。
  2. 404が返るだけで安全と判断しない。 User-AgentによってHTTPステータスやHTMLが変わる場合があります。
  3. ファイルとデータベースの両方を調べる。 .htaccess、PHP設定、テーマ、プラグイン、キャッシュ、投稿データなどを段階的に切り分けることが大切です。
  4. 復旧後も同じURL・同じ条件で検証する。 症状が改善したかを、HTTPステータスやレスポンス内容で比較できます。

今回は最終的にWordPressリカバリーで改善しましたが、侵入経路や不正コードの場所までは特定できませんでした。今後はWordPress本体・プラグインの更新、不要なプラグインの整理、管理者アカウントと認証情報の見直し、バックアップ、ログ監視を継続していくつもりです。

WordPressで突然、見知らぬ商品ページが検索結果に現れた場合は、ぜひ「通常アクセスとGooglebotで返される内容が同じか」を確認してみてください。今回のように、原因を絞り込む大きな手掛かりになるかもしれません。

スポンサーリンク
タイトルとURLをコピーしました