0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI要約が「詐欺ではありません」と答える仕組み、踏み台はあなたのサイトの検索窓

0
Last updated at Posted at 2026-07-28

投資グループに誘われた人が、お金を振り込む前に一応グループ名を検索してみます。検索結果には「○○は詐欺ではない」「○○で儲かりました」が並び、ページ上部のAI要約も「○○は詐欺ではありません」と答える。安心して振り込む。

この手口を、警視庁サイバーセキュリティ対策課が2026年7月24日に注意喚起しました。「検索して裏を取る」という防衛行動そのものが、罠に組み込まれています。

怖いのはここからです。この検索結果の汚染に、高度なハッキングは必要ありません。どこのサイトにもある検索窓の仕様の悪用で実現できる可能性が指摘されています。あなたが運用しているサイトの検索窓が、知らないうちに片棒を担がされるかもしれません。

操り糸で吊り上げられた偽の巨大チェックマークと、それを見上げる人物のイラスト

この報道を読んだとき、最初に浮かんだのは「これはどういう仕組みでやっているんだ?」という疑問でした。私は普段LLMO(AI検索に引用されるための最適化)を扱っているので、LLMOやSEOの周辺で話題になっている検索汚染系の技術ではないか、と当たりをつけて調べてみました。行き着いた答えは、2023年から知られていた古典的な手口。「サイト内検索スパム」です。

この記事では、その仕組みと、なぜAI要約まで汚染されるのかというRAGの構造的な弱点、そして開発者側でできる防御実装(noindex / X-Robots-Tag / 0件時404)をまとめます。

何が起きているのか

警視庁の発表によると、SNS型投資詐欺グループがWeb検索の仕組みを悪用し、検索結果を汚染する手口が確認されました。被害者が誘導先のSNSグループやサイトの名称を検索すると、「○○は詐欺ではない」「○○は素晴らしい」といった肯定的な情報が検索結果に並びます。検索結果をもとにしたAI要約でも「○○は詐欺ではありません」と表示されるとのことです。

警視庁は検索結果を操作した具体的な方法を明らかにしていません。ただ、検索結果に不正な情報を目立たせる手法は「SEOポイズニング」と呼ばれ、その一種に「サイト内検索スパム」があります。報道でも、この手口で汚染された検索結果をAIが参照した可能性が指摘されています。

従来のSEOポイズニングは「検索結果に偽サイトを混ぜ込む」ものでした。今回はその先です。AI要約が汚染された結果を根拠に「詐欺ではありません」と太鼓判を押すところまで到達しています。

仕組み: サイト内検索スパムの3ステップ

検索窓を持つサイトの多くは、/search?q=キーワード のようなURLで検索結果ページを返します。攻撃の前提になるのは、この実装によくある2つの性質です。

  • URLのクエリパラメータに任意の文字列を入れられる
  • 入力されたクエリを、検索結果ページの <title><h1> にそのまま反射する(「"○○" の検索結果 | 株式会社△△」のような表示)

攻撃は3ステップで進みます。

  1. 攻撃者が、信頼あるドメインのサイト内検索URLを「作文」する。example.co.jp/search?q=○○は詐欺ではない のように、検索窓に打ち込む必要すらなく、URLを組み立てるだけです
  2. そのURLへのリンクを、攻撃者が管理する外部サイトに設置する
  3. Googlebotがリンクをたどって検索結果ページを発見し、クロールしてインデックスに登録する。以後、Web検索の結果に「○○は詐欺ではない | 株式会社△△」という見出しが、正規ドメインとともに表示され得る

このとき、踏み台にされた企業サイトは改ざんも侵入もされていません。攻撃者がやったのは「URLを作ってリンクを張った」だけです(私は最初にこの手口の解説を読んだとき、「え、それだけ?」と声が出ました)。道具も要りません。突かれているのは脆弱性ではなく仕様です。

この手口は、SEOコンサルティング企業JADEの村山佑介さんが2023年2月のブログで「他社サイトのサイト内検索URLを利用するスパム」として注意喚起した時点から急増が観測されていた、いわば既知の攻撃面です。

検索した人から見ると、「あの会社のサイトに『詐欺ではない』と書いてある」ように見えます。ドメインが積み上げてきた信頼が、無関係な第三者の文言にそのまま又貸しされる構造です。

なぜAI要約まで嘘をつくのか

検索結果ページの上部に出るAI要約(GoogleのAI Overviewなど)は、仕組みとしてはRAG(Retrieval-Augmented Generation)に近い構造です。内部仕様は公開されていませんが、少なくともユーザーの質問に関連するページを検索インデックスから取得し、その内容をもとに要約を組み立てていることは観測できます。

AI側から見ると、取得したのは「信頼あるドメイン上に書かれたテキスト」です。真偽の検証はしません。答えの確からしさは、ソースの権威性と、複数ソースの一致度で判断されます。攻撃者が複数のサイト内検索URLに同じ文言を仕込めば、AIには「複数の信頼できるソースが一致している」ように見えてしまいます。

権威性をシグナルとして重視するほど、権威の又貸しに弱くなる。皮肉な構造です。真面目にソースの権威を評価するAIほど、この手口にはよく騙されます。

整理すると、検索インデックスが上流、AI要約は下流。上流が汚染されれば、下流も汚染されます。AI要約側のフィルタ改善を待つより、反射面を持つサイト側が汚染経路を塞ぐほうが早く、確実です。

あなたのサイトは大丈夫か: 5分セルフチェック

自分のサイトが踏み台にされ得るか。次の手順で確認できます。やることは3つ、5分で終わります。

# 1. 検索結果ページがインデックスされていないか(Google検索で)
site:example.com inurl:search
site:example.com inurl:"?s="

# 2. 不審な文言でインデックスされていないか
site:example.com 詐欺
site:example.com 副業
# 3. 検索結果ページのレスポンスにnoindexが付いているか
curl -sI "https://example.com/search?q=test" | grep -i x-robots-tag

# ヘッダに無ければHTML側のmetaタグを確認
curl -s "https://example.com/search?q=test" | grep -i '<meta name="robots"'

site: 検索は簡易チェックです。Googleも網羅的な結果を返すとは保証していないので、確定はGoogle Search Consoleで取ります。「インデックス作成 > ページ」と「検索パフォーマンス > ページ」で、検索結果ページのURL(/search?s= を含むもの)が登録・表示されていないかを確認できます。

あわせて、検索結果テンプレートがクエリを <title><h1> にそのまま反射しているかも見ておいてください。反射があり、かつインデックス可能。この組み合わせが攻撃面になります。

なお、静的サイトでよくあるクライアントサイド検索(JSがブラウザ内で絞り込む方式)は、サーバーがクエリごとに別内容のHTMLを返さないため、この攻撃面自体がありません。

防御実装

方針は2択。JADEの推奨する対策をベースに整理します。

対策 効果 注意点
<meta name="robots" content="noindex"> 検索結果ページをインデックスから確実に除外 robots.txtでブロックすると読まれず無効化される
X-Robots-Tag: noindex ヘッダ テンプレート改修なしにインフラ層で一括適用 同上
0件ヒット時にnoindex(または404) 検索流入を維持しつつスパムを遮断 404は正当な0件クエリの体験を壊すことがある。動的にコンテンツが増えるサイトは特に注意
robots.txtで Disallow: /search クロール自体を抑制 単独では不完全。ブロック中のURLも外部リンク経由でインデックスされ得る

使い分けはシンプルです。

  • 検索結果ページで検索流入を狙っていない場合: 検索結果ページ全体にnoindexを付けます。最も単純で確実です
  • 検索流入を維持したい場合: 0件ヒット時にnoindexを返します(要件によっては404)。「○○は詐欺ではない」のような自然文クエリはヒット0件になりやすいため、これだけでスパムの大半を弾けます

ひとつ、嫌な二律背反があります。noindexはクローラーがページを読んで初めて効きます。robots.txtで Disallow するとページが読まれなくなり、noindexも無効化されます。Googleのドキュメントにも「noindexルールを有効にするには、ページがrobots.txtでブロックされていない状態にする必要がある」と明記されています。noindexを効かせたいURLは、robots.txtでブロックしない。これが原則です。

実装例をいくつか挙げます。

WordPressの検索結果ページ(?s=)は、Yoast SEOなどのプラグインがデフォルトでnoindexを付けます。素のテーマの場合は、WordPress 5.7以降の wp_robots フィルタで指定します(コアやプラグインの出力と衝突しません)。

// functions.php
add_filter('wp_robots', function ($robots) {
    if (is_search()) {
        $robots['noindex'] = true;
    }
    return $robots;
});

Next.js(App Router)なら、検索ページのmetadataで指定します。

// app/search/page.tsx
export const metadata = {
  robots: { index: false, follow: true },
};

インフラ層で一括適用するなら、nginxでヘッダを付けます。この例はパス型(/search)の検索URL向けで、?s= のようなクエリパラメータ型には当たらないため、その場合は $arg_s での分岐など別の書き方が要ります。また、nginxの add_header はlocation内に1つでも書くと上位で定義したヘッダを引き継がなくなるので、セキュリティヘッダ等を上位に置いているサイトでは、そのlocationで再宣言してください。

location /search {
    add_header X-Robots-Tag "noindex" always;
    # 上位の add_header (セキュリティヘッダ等) はここで再宣言が必要
    proxy_pass http://app;
}

検索結果ページのnoindexは、スパム対策を抜きにしてもSEO上の定石です。重複コンテンツの温床とクロールバジェットの浪費を防げるので、今回を機に入れておいて損はありません。

まとめ

  • 警視庁が注意喚起した「詐欺ではありません」汚染は、サイト内検索スパムで説明がつく。突かれているのは、クエリを反射してインデックスを許す仕様そのもの
  • AI要約は検索インデックスを上流とするRAGなので、上流の汚染がそのまま答えになる。AI側の改善を待つより、サイト側で反射面を塞ぐほうが早い
  • 対策はnoindexが軸。noindexを効かせたいURLをrobots.txtでブロックしない。検索流入を残したいなら0件時noindex

自分のサイトを持っている方は、今日 site:自分のドメイン inurl:search を検索してみてください。何か出てきたら、この記事の防御実装の出番です。あなたのサイトの検索窓は、誰かの「詐欺ではありません」を運んでいませんか。

なお、この「検索結果ページがインデックス可能かどうか」を機械チェックする仕組みは、私が関わっているOSSのチェッカーにも組み込めないか検討を始めています(open-llmo/llmo-checker#2)。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?