最終更新日:2026年8月15日
パクリサイトへの対策として、自作のアクセス解析CGI(Gemini監修)にて、不審なアクセスを WordPress のセキュリティプラグイン「Kadence Security」で BAN して対応していますが、それだけは不十分なので、追加対策として、Geminiが監修した「REST APIアクセス拒否」のスクリプトを実装しました。
近年、特定のカテゴリーにおいて、Google 検索での記事のパクリサイトが大量に沸いており、当サイトも相当な被害を受けています。
その主な記事は、家電製品(冷蔵庫、エアコン、ドライヤーなど)、スマホ、タブレット、パソコン、カラオケ機器、PC周辺機器(プリンターなど)、設備機器(レンジフード、ウオシュレット、防犯カメラなど)、おもちゃ、ファッションブランドなどに集中しています。
それらの対象記事(60以上)については、毎日チェックすると、1日100件くらいのパクリ記事が沸いているため、「Google Search Console」の通報フォーム(DMCAなど)で報告してもとても追いつかない状況となっております。
Webサイトにおける対策としては、以下で紹介した自作のアクセス解析CGI「Gemini監修による超軽量アクセス解析CGIプログラム(Perl)を公開」にて、不審なアクセスを WordPress のセキュリティプラグイン「Kadence Security」で BAN して対応しています。
【パクリサイト対策】未ログインユーザーに対するREST APIアクセスを完全に拒否
なお、未ログイン時のREST APIを完全に塞ぐと、以下の機能が動作しなくなるため、注意が必要です。
- Jetpack:アクセス解析や自動連携ができなくなります。
- お問い合わせフォーム(Contact Form 7など):非同期(Ajax風)の送信処理にREST APIを使っている場合、一般ユーザーからの送信がエラーになります。
- ブログカード(oEmbed):外部サイトに自分の記事のブログカードを貼ってもらう機能が動かなくなります。
- スマホアプリ(WordPress公式アプリ):アプリからログインして執筆できなくなります。 [1, 2]
※なお、管理画面(Gutenbergエディタなど)は自身が「ログイン状態」で操作するため、先ほどのコードでも全く影響を受けず正常に動きます。
そこで、これらの事を踏まえ、Contact Form 7 と Jetpack を完全に生かしたまま、BOTの記事データ取得だけを401エラー(拒否)にする、Gemini 監修の修正版のコードと解説を以下に転載します。
functions.php の末尾に追記してください。
/**
* 【パクリサイト対策:完全版】
* 未ログインユーザーに対するREST APIアクセスを拒否(WPP・管理画面・Gemini・CF7・Jetpack対応)
*/
add_filter('rest_authentication_errors', function($result) {
// 1. すでに他のプラグイン等で認証(Jetpackの署名通信など)が通っている場合はスルー
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
// 2. 管理者がログインしている場合、または管理画面・Ajaxからのバックグラウンド通信(Gemini等)はすべて許可
if ( is_user_logged_in() || is_admin() || (defined('DOING_AJAX') && DOING_AJAX) ) {
return $result;
}
// 3. 【未ログイン(匿名)】のアクセスに対する処理
if ( isset($_SERVER['REQUEST_URI']) ) {
$url = $_SERVER['REQUEST_URI'];
// 【ホワイトリスト】一般ユーザーのブラウザ上で動く必要なAPI通信は許可
if (
strpos($url, '/wp-json/contact-form-7/') !== false || // お問い合わせ
strpos($url, '/wp-json/wordpress-popular-posts/') !== false // 人気記事ランキング
) {
return $result;
}
}
// 4. 上記以外(botによる匿名での記事一覧・全文データ引っこ抜き /wp-json/wp/v2/posts など)をすべて遮断
return new WP_Error('rest_not_logged_in', 'REST API restricted.', array('status' => 401));
});
このコードで影響が出ない理由
- Jetpack: Jetpackが外部からデータを取得・同期する際は、リクエストに認証が付与されます。そのため、コードの1番最初(
true === $resultの判定)で「認証済み」とみなされて自動パスします。IPアドレスをホワイトリストに登録する必要は一切ありません。 - Contact Form 7: 3番の記述により、フォーム送信時に発生する匿名API通信(
/wp-json/contact-form-7/v1/...)ならびに、WPP (WP Popular Posts) だけをピンポイントで例外許可しています。 - 管理画面(Gutenberg): あなたがログインした状態で執筆するため、2番の判定で無条件でパスします。[1]
この設定を本番環境に適応する前に、まずは一度テスト環境、もしくはアクセスの少ない時間帯に functions.php へ記述し、「お問い合わせフォームが正常に送れるか」「Jetpackのダッシュボードにエラーが出ないか」をご確認いただくのが一番確実です。
このコードにより、BOTが裏口(JSONデータ)から爆速で100件の記事をダウンロードしていく不条理な挙動は、ほぼ完全にシャットアウトできます。ぜひお試しください。
テストサイトでの3大検証ポイント
- 通常のお問い合わせ送信テスト
- 手順: ログインしていないブラウザ(シークレットウィンドウなど)でお問い合わせページを開き、テスト送信します。
- 合格基準: エラーにならず、通常通り「送信が完了しました」と表示されればクリアです。
- 記事データの「ぶっこぬき拒否」テスト(最重要)
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
https://テストサイトのURL/wp-json/wp/v2/postsと入力してアクセスします。 - 合格基準: 記事のJSONデータが表示されず、画面に
{"code":"rest_not_logged_in","message":"REST API restricted."...}という401エラー(拒否画面)が出れば大成功です。パクリBOTの侵入経路が塞がれた証拠です。
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
- Jetpackの同期確認(本番移行後でも可)
- 手順: 本番に反映した際、WordPress管理画面の「Jetpack」設定ページで「連携エラー」の警告が出ていないか、アクセス統計が通常通り更新されているかを確認します。
本番サイトへ導入する際のアドバイス
テストサイトでクリアできていれば本番導入への障壁はほぼありませんが、移行時は以下だけ念のためご留意ください。
- 本番移行直後の最終確認:
本番サイトのfunctions.phpにコードを反映した直後、「シークレットウィンドウ(未ログイン状態)でお問い合わせフォーム(Contact Form 7)から一度テスト送信してみる」ことだけ実施してください。ここが正常に通れば完璧なディフェンス網の完成です。
これにより、毎日100件もの不条理なDMCA通報に追われ、Googleの遅い対応にイライラさせられていた不毛な時間から、大きく解放されるはずです。
もし今後、これでもすり抜けて「画面(ブラウザ)のHTMLを直接解析して強引にコピーしてくる」タイプのしつこいBOTが残るようであれば、次のステップとして前述した Cloudflare(クラウドフレア)の無料WAFによる「JSチャレンジ(人間認証)」 を検討しましょう。
よって、対策は限られますが、以下の記事「サイト運営者が取れる追加の防衛策」などで、対応するしかないようです。
- 🛡️サイト運営者が取れる追加の防衛策
- リスト2(先頭に絵文字無し)
- Listing 3
段落ブロック
【拡大サイズのリスト】
- 通常のお問い合わせ送信テスト
- 手順: ログインしていないブラウザ(シークレットウィンドウなど)でお問い合わせページを開き、テスト送信します。
- 合格基準: エラーにならず、通常通り「送信が完了しました」と表示されればクリアです。
- 記事データの「ぶっこぬき拒否」テスト(最重要)
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
https://テストサイトのURL/wp-json/wp/v2/postsと入力してアクセスします。 - 合格基準: 記事のJSONデータが表示されず、画面に
{"code":"rest_not_logged_in","message":"REST API restricted."...}という401エラー(拒否画面)が出れば大成功です。パクリBOTの侵入経路が塞がれた証拠です。
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
- Jetpackの同期確認(本番移行後でも可)
- 手順: 本番に反映した際、WordPress管理画面の「Jetpack」設定ページで「連携エラー」の警告が出ていないか、アクセス統計が通常通り更新されているかを確認します。
【通常サイズのリスト】
- 通常のお問い合わせ送信テスト
- 手順: ログインしていないブラウザ(シークレットウィンドウなど)でお問い合わせページを開き、テスト送信します。
- 合格基準: エラーにならず、通常通り「送信が完了しました」と表示されればクリアです。
- 記事データの「ぶっこぬき拒否」テスト(最重要)
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
https://テストサイトのURL/wp-json/wp/v2/postsと入力してアクセスします。 - 合格基準: 記事のJSONデータが表示されず、画面に
{"code":"rest_not_logged_in","message":"REST API restricted."...}という401エラー(拒否画面)が出れば大成功です。パクリBOTの侵入経路が塞がれた証拠です。
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
- Jetpackの同期確認(本番移行後でも可)
- 手順: 本番に反映した際、WordPress管理画面の「Jetpack」設定ページで「連携エラー」の警告が出ていないか、アクセス統計が通常通り更新されているかを確認します。
【部分サイズ指定】
- 通常のお問い合わせ送信テスト
- 手順: ログインしていないブラウザ(シークレットウィンドウなど)でお問い合わせページを開き、テスト送信します。
- 合格基準: エラーにならず、通常通り「送信が完了しました」と表示されればクリアです。
- 記事データの「ぶっこぬき拒否」テスト(最重要)
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
https://テストサイトのURL/wp-json/wp/v2/postsと入力してアクセスします。 - 合格基準: 記事のJSONデータが表示されず、画面に
{"code":"rest_not_logged_in","message":"REST API restricted."...}という401エラー(拒否画面)が出れば大成功です。パクリBOTの侵入経路が塞がれた証拠です。
- 手順: ログアウトした状態で、ブラウザのアドレスバーに直接
- Jetpackの同期確認(本番移行後でも可)
- 手順: 本番に反映した際、WordPress管理画面の「Jetpack」設定ページで「連携エラー」の警告が出ていないか、アクセス統計が通常通り更新されているかを確認します。