2025年11月13日

2025年11月13日

クロスサイトリクエストフォージェリ(CSRF)攻撃の脅威

ある日突然、自分が管理者権限を失った理由

クライアントから緊急の連絡が入った。「WordPressの管理画面に入れなくなったんです。パスワードが間違っているって表示されます」

おかしいな、と思いながら状況を確認すると、もっと深刻な問題が発覚した。そのクライアントの管理者アカウントが、知らない間に「購読者」に降格されていたんだ。しかも、見覚えのない新しい管理者アカウントが作られていた。

ログを調べて分かったのは、CSRF攻撃を受けていたということだった。クライアントは仕事中に、取引先から送られてきたメールのリンクをクリックしただけ。それだけで、WordPressにログインしている状態のまま、意図しない操作が実行されてしまったんだ。

CSRF攻撃は、ユーザーの信頼を悪用する。

パスワードが強固でも、セキュリティプラグインを入れていても、CSRF攻撃は防げない。なぜなら、攻撃者はあなたのパスワードを知る必要がないからだ。あなたが既にログインしている状態を利用して、あなたの権限で勝手に操作を実行する。これがCSRF攻撃の恐ろしさなんだ。

この記事では、CSRF攻撃とは何か、どのように動作するのか、そしてWordPressサイトを守るための実践的な対策方法を解説する。技術的な話も出てくるけど、できるだけ分かりやすく説明していくから、最後まで読んでほしい。

CSRF攻撃とは何か - 見えない攻撃の仕組み

信頼関係を逆手に取る攻撃手法

CSRF(Cross-Site Request Forgery)は、日本語で「クロスサイトリクエストフォージェリ」または「リクエスト強要」と呼ばれる攻撃手法だ。簡単に言うと、あなたが意図しない操作を、あなたの権限で勝手に実行させる攻撃なんだ。

通常、ウェブサイトはログインしているユーザーを「信頼」している。WordPressにログインした状態でリクエストを送ると、そのリクエストは正当なユーザーからのものだと判断される。CSRF攻撃は、この信頼関係を悪用するんだ。

攻撃者は、あなたがWordPressにログインしている状態で、罠を仕掛けたリンクをクリックさせる。そのリンクから送られるリクエストは、あなたのブラウザから発信される。だから、WordPressは「これは正当なユーザーからのリクエストだ」と判断して、そのまま実行してしまう。

実際のCSRF攻撃のシナリオ

具体的なシナリオを見てみよう。こういう流れで攻撃が成立する。

  1. あなたはWordPressの管理画面にログインしている
  2. 別のタブでメールをチェックしている
  3. 取引先を装ったメールに「請求書を確認してください」というリンクがある
  4. リンクをクリックする
  5. 実は、そのリンクは攻撃者が用意したページへの誘導だった
  6. そのページには、WordPressに対して「新しい管理者アカウントを作成する」というリクエストを送る隠しフォームが埋め込まれている
  7. ページを開いた瞬間、JavaScriptが自動的にそのフォームを送信する
  8. あなたのブラウザから、あなたの権限でリクエストが送られる
  9. WordPressは正当なリクエストだと判断して、新しい管理者アカウントが作成される

この一連の流れの中で、あなたは何も気づかない。ページが開いて、すぐに閉じるか別のページにリダイレクトされる。でも、その数秒の間に、攻撃は完了している。

なぜWordPressがターゲットになるのか

WordPressがCSRF攻撃のターゲットになりやすい理由がいくつかある。

まず、WordPressは世界中で広く使われているCMSだ。攻撃者にとっては、一つの攻撃手法を開発すれば、何千何万ものサイトに適用できる。効率がいいターゲットなんだよね。

次に、WordPressには強力な管理機能がある。ユーザーの追加・削除、プラグインのインストール、テーマの変更、投稿の編集。これらすべてが、CSRF攻撃の標的になり得る。

僕が実際に調査したケースでは、企業のWordPressサイトが狙われたことがあった。そのサイトは社内の複数の担当者が管理していて、みんなログインしっぱなしで作業していた。ある担当者が、業務メールに添付されていたPDFのリンクをクリックしたところ、そのリンクが罠だったんだ。気づいたときには、不審なプラグインが3つもインストールされていた。

さらに、多くのWordPressユーザーは、管理画面にログインしたまま、他のウェブサイトを閲覧することがある。記事を書きながら調べ物をしたり、メールをチェックしたり。この「ながら作業」が、CSRF攻撃を成功させる条件を整えてしまうんだ。

特に危険なのは、複数のタブを開いて作業する習慣だ。WordPress管理画面を開いたまま、SNSをチェックしたり、ニュースサイトを見たり。この状態で、悪意のあるリンクを踏んでしまうと、ログイン状態が悪用される可能性が高まる。

CSRF攻撃で何ができてしまうのか

管理者アカウントの乗っ取り

最も深刻な被害は、管理者アカウントの乗っ取りだ。攻撃者は、CSRF攻撃を使って以下のようなことができる。

新しい管理者アカウントの作成

攻撃者が最も狙うのがこれだ。新しい管理者アカウントを作成されると、攻撃者は正規のルートでサイトにアクセスできるようになる。

<?php
// CSRF攻撃で送られる可能性のあるリクエストの例
// wp-admin/user-new.phpへのPOSTリクエスト
$params = array(
    'action' => 'createuser',
    'user_login' => 'attacker',
    'email' => 'attacker@evil.com',
    'role' => 'administrator',
    'pass1' => 'SecretPassword123!',
    'pass2' => 'SecretPassword123!'
);
?>

このリクエストが、あなたの権限で送信されると、攻撃者のアカウントが管理者として作成される。そして攻撃者は、いつでも好きな時にサイトにログインできるようになる。

既存ユーザーの権限変更

もっと巧妙な攻撃では、既存のユーザーの権限を変更する。例えば、あなたの管理者アカウントを「購読者」に降格させて、代わりに攻撃者のアカウントを管理者に昇格させる。

こうすると、あなたは管理画面にアクセスできなくなる。でも、ログイン自体はできるから、すぐには異常に気づかない。その間に、攻撃者は好き放題サイトを操作できるんだ。

プラグインやテーマの操作

管理者権限があれば、プラグインやテーマも自由に操作できる。CSRF攻撃で以下のようなことが可能だ。

悪意のあるプラグインのインストール

攻撃者が用意したバックドア付きのプラグインをインストールさせる。一見普通のプラグインに見えるけど、裏でサーバー上のファイルにアクセスしたり、データベースの情報を外部に送信したりする。

既存プラグインの無効化

セキュリティプラグインを無効化されると、サイトの防御が一気に弱くなる。Wordfenceやセキュリティ関連のプラグインを狙われることが多いんだ。

テーマファイルの編集

WordPressの管理画面には、テーマエディタという機能がある。これを使って、テーマのPHPファイルを直接編集できる。CSRF攻撃で、このエディタを通じて悪意のあるコードを注入されることもある。

コンテンツの改ざん

記事や固定ページの内容を勝手に変更されることもある。

  • スパムリンクの追加
  • マルウェアを配布するスクリプトの埋め込み
  • フィッシングサイトへの誘導
  • 不適切なコンテンツへの差し替え

こういった改ざんは、SEOに悪影響を与えるだけじゃなく、サイトの信頼性を大きく損なう。訪問者がマルウェアに感染したら、あなたのサイトの責任にもなりかねないんだ。

実際にあった事例では、ニュースサイトの記事に、気づかれないようにスパムリンクが大量に追加されていた。リンクのテキストは記事の文章に溶け込んでいて、一見すると正常に見える。でも、リンク先は怪しいサイトばかり。これが数ヶ月続いて、Googleからペナルティを受けてしまった。検索順位が大きく下がり、サイトのトラフィックは半減した。復旧には半年以上かかったんだ。

設定の変更

サイトの基本設定も、CSRF攻撃の標的になる。

  • サイトのタイトルやキャッチフレーズの変更
  • 一般公開設定の変更(検索エンジンにインデックスさせない設定にする)
  • パーマリンク構造の変更(すべてのURLが404エラーになる)
  • コメント設定の変更(スパムコメントを自動承認する設定にする)

特に危険なのは、.htaccessやwp-config.phpの設定を変更されること。これらはサイトの根幹に関わるファイルだから、改ざんされると取り返しのつかない被害になることもある。

WordPressに組み込まれているCSRF対策

Nonceの仕組み

実は、WordPressにはCSRF攻撃を防ぐための仕組みが標準で組み込まれている。それが「Nonce」(ナンス)だ。

Nonceは「Number used once」の略で、一度だけ使える使い捨ての番号のことだ。WordPressでは、フォームやリンクに固有の認証トークンを付けて、そのリクエストが正当なものかどうかを確認している。

仕組みはこうだ:

  1. WordPressがフォームを生成する時、Nonceという隠しフィールドを追加する
  2. このNonceは、現在のユーザー、操作の種類、タイムスタンプから生成される
  3. フォームが送信されると、WordPressはNonceの値をチェックする
  4. Nonceが正しければ、リクエストを処理する
  5. Nonceが間違っていたり、期限切れだったりすると、リクエストを拒否する

外部サイトから送られるCSRF攻撃のリクエストには、正しいNonceが含まれていない。だから、WordPressはそのリクエストを拒否できるんだ。

Nonceの実装例

開発者向けの話になるけど、WordPressでNonceを実装する方法を見てみよう。

フォームにNonceを追加する

<?php
// フォームの例
echo '<form method="post" action="">';

// Nonceフィールドを追加
wp_nonce_field( 'my_action', 'my_nonce_field' );

echo '<input type="text" name="username" />';
echo '<input type="submit" value="送信" />';
echo '</form>';
?>

wp_nonce_field()関数が、隠しフィールドとしてNonceを生成する。第一引数は「アクション名」、第二引数は「フィールド名」だ。

Nonceを検証する

<?php
// フォーム送信時の検証
if ( isset( $_POST['my_nonce_field'] ) ) {
    // Nonceを検証
    if ( ! wp_verify_nonce( $_POST['my_nonce_field'], 'my_action' ) ) {
        // Nonceが無効な場合、処理を中断
        wp_die( 'セキュリティチェックに失敗しました' );
    }

    // Nonceが有効な場合、処理を続行
    $username = sanitize_text_field( $_POST['username'] );
    // ... 処理を続ける
}
?>

wp_verify_nonce()関数で、Nonceが正しいかどうかを確認する。これがfalseを返したら、CSRF攻撃の可能性があるということだ。

AJAXリクエストでのNonce

最近のWordPressでは、AJAXを使った非同期処理も多い。AJAXでもNonceは必須だ。

// JavaScriptでNonceを送信
jQuery.ajax({
    url: ajaxurl,
    type: 'POST',
    data: {
        action: 'my_ajax_action',
        nonce: my_ajax_object.nonce,  // PHPから渡されたNonce
        username: jQuery('#username').val()
    },
    success: function(response) {
        // 成功時の処理
    }
});
<?php
// PHP側でのNonce検証
add_action( 'wp_ajax_my_ajax_action', 'my_ajax_handler' );

function my_ajax_handler() {
    // Nonceを検証
    check_ajax_referer( 'my_ajax_nonce', 'nonce' );

    // 検証に成功したら処理を続行
    $username = sanitize_text_field( $_POST['username'] );
    // ... 処理

    wp_send_json_success( array( 'message' => '成功しました' ) );
}
?>

Nonceだけでは不十分な場合

Nonceは強力なCSRF対策だけど、完璧じゃない。いくつかの問題点がある。

Nonceの有効期限

WordPressのNonceは、デフォルトで24時間有効だ。つまり、攻撃者が何らかの方法で有効なNonceを入手できれば、24時間以内ならそれを使って攻撃できる。

古いプラグインやテーマ

問題は、すべてのプラグインやテーマがNonceを正しく実装しているわけじゃないということだ。特に古いプラグインや、品質の低いテーマでは、Nonceチェックが省略されていることがある。

こういったプラグインを使っていると、WordPressのコア機能はCSRF対策されていても、プラグインの機能は無防備なままになってしまう。

カスタム機能の実装ミス

自社開発や、外注で作ってもらったカスタム機能も要注意だ。開発者がセキュリティに疎いと、Nonceチェックを実装していないことがある。

僕が過去に見たケースでは、カスタムプラグインがCSRF対策をまったく実装していなくて、そこを狙われた事例があった。開発者に確認したら「そんな機能があることを知らなかった」って言われて、正直ガッカリしたよ。

CSRF攻撃から守るための実践的な対策

Same-Site Cookie属性の活用

最近のブラウザは、Same-Site Cookie属性という機能をサポートしている。これは、クッキーを「同じサイト内でのみ送信する」ように制限できる機能だ。

WordPressのログインクッキーにSame-Site属性を設定すると、外部サイトからのリクエストにはクッキーが送信されなくなる。つまり、外部サイトから攻撃を仕掛けられても、ログイン状態を利用できないんだ。

wp-config.phpでの設定

WordPress 5.4以降では、Same-Site Cookie属性がデフォルトで有効になっている。でも、明示的に設定することもできる。

<?php
// wp-config.phpに追加
// Same-Site Cookie属性を設定
@ini_set( 'session.cookie_samesite', 'Strict' );

// セキュアな接続(HTTPS)でのみクッキーを送信
@ini_set( 'session.cookie_secure', '1' );

// JavaScriptからクッキーにアクセスできないようにする
@ini_set( 'session.cookie_httponly', '1' );
?>

Strictに設定すると、最も厳格な制限になる。すべての外部サイトからのリクエストでクッキーが送信されなくなる。

ただし、これは若干不便になることもある。例えば、外部の決済サービスから戻ってきた時にログアウトしてしまう、といった問題が起こる可能性があるんだ。

そういう場合は、Laxという設定もある。これは、安全なリクエスト(GETリクエストなど)では外部サイトでもクッキーを送信するけど、危険なリクエスト(POSTリクエストなど)では送信しない、というバランスの取れた設定だ。

<?php
@ini_set( 'session.cookie_samesite', 'Lax' );
?>

リファラーチェックの実装

リファラー(Referer)というのは、リクエストがどのページから送られてきたかを示す情報だ。これをチェックすることで、外部サイトからのリクエストを検出できる。

WordPressのプラグインやカスタム機能で、リファラーチェックを追加する方法がある。

<?php
function check_referer_for_admin_actions() {
    // 管理画面でのPOSTリクエストの場合
    if ( is_admin() && $_SERVER['REQUEST_METHOD'] === 'POST' ) {
        $referer = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '';
        $site_url = site_url();

        // リファラーが自サイト以外からの場合、処理を中断
        if ( strpos( $referer, $site_url ) !== 0 ) {
            wp_die( '不正なリクエストが検出されました' );
        }
    }
}
add_action( 'admin_init', 'check_referer_for_admin_actions' );
?>

ただし、リファラーチェックだけでは不十分だ。リファラーはユーザーのブラウザ設定やプライバシー拡張機能で送信されないこともある。だから、Nonceと組み合わせて使うのがベストだ。

プラグインとテーマの選定

CSRF対策で最も重要なのは、信頼できるプラグインとテーマを使うことだ。

公式ディレクトリから選ぶ

WordPress.orgの公式ディレクトリに登録されているプラグインは、基本的なセキュリティレビューを受けている。完璧じゃないけど、まったく野良のプラグインよりは遥かに安全だ。

更新が活発なものを選ぶ

最終更新日が何年も前のプラグインは避けるべきだ。セキュリティの脆弱性が見つかっても、修正されない可能性が高い。

レビューとインストール数を確認

多くのユーザーが使っていて、評価が高いプラグインの方が信頼できる。問題があれば、レビューに書かれていることが多いからね。

不要なプラグインは削除

使っていないプラグインは、無効化するだけじゃなくて、完全に削除すべきだ。無効化していても、脆弱性があれば攻撃される可能性がある。

セキュリティプラグインの活用

セキュリティプラグインを導入することで、CSRF攻撃をある程度防げる。

Wordfence Security

Wordfenceは、不審なリクエストパターンを検出して、自動的にブロックする機能がある。CSRF攻撃のような異常な動作を検知すると、アラートを出してくれる。

All In One WP Security & Firewall

このプラグインは、ログインページへのアクセス制限や、管理画面のURL変更など、多層防御の機能を提供している。CSRF攻撃が成功する前の段階で、攻撃者をブロックできる可能性が高まる。

ただし、セキュリティプラグインに頼りすぎるのも危険だ。プラグイン自体に脆弱性があったら、逆にセキュリティホールになる。だから、プラグインは常に最新版に保って、複数のプラグインで多層防御を構築するのがいいと思う。

ユーザー教育の重要性

技術的な対策も大事だけど、ユーザー教育も同じくらい重要だ。CSRF攻撃は、ユーザーの行動を利用した攻撃だからね。

ログアウトの習慣

WordPressの作業が終わったら、必ずログアウトする習慣をつける。ログインしたままだと、他のサイトを見ている間に攻撃される危険性がある。

怪しいリンクはクリックしない

メールやSNSで送られてくるリンクは、すぐにクリックしない。送信元が本当に信頼できるか、URLが怪しくないか、確認する癖をつけよう。

別のブラウザを使い分ける

僕がクライアントに勧めているのは、WordPress管理用とそれ以外で、ブラウザを使い分ける方法だ。例えば、Chromeでは一般的なウェブ閲覧をして、FirefoxではWordPress管理だけをする。

こうすると、一般的なウェブサイトを見ている時にCSRF攻撃のリンクを踏んでも、WordPressにはログインしていないから、攻撃は成立しない。

実際に、この方法を導入したクライアントは、それ以降CSRF攻撃の被害に遭っていない。最初は面倒だと言っていたけど、慣れてしまえば自然にできるようになる。セキュリティのためのちょっとした手間だと思えば、それほど負担じゃないんだよね。

定期的なパスワード変更とセッション管理

長時間ログインしっぱなしにしない、というのも大事だ。WordPress管理画面で作業していない時は、ログアウトする。あるいは、ブラウザを閉じる。これだけで、攻撃のリスクは大きく下がる。

よくある質問(FAQ)

Q1: CSRF攻撃とXSS攻撃の違いは?

どちらもクロスサイト系の攻撃だから、混同されやすいんだよね。でも、仕組みは全然違う。

XSS(クロスサイトスクリプティング)攻撃

  • サイトに悪意のあるスクリプトを注入する
  • 訪問者のブラウザでそのスクリプトが実行される
  • クッキーの盗聴、情報の窃取などが目的

CSRF(クロスサイトリクエストフォージェリ)攻撃

  • ユーザーに意図しないリクエストを送信させる
  • ユーザーの権限で不正な操作を実行する
  • アカウントの乗っ取り、設定の変更などが目的

簡単に言うと、XSSは「攻撃コードをサイトに埋め込む」攻撃で、CSRFは「ユーザーに操作させる」攻撃だ。対策方法も異なるから、両方への対策が必要なんだ。

Q2: WordPressのNonceはどのくらい安全?

WordPressのNonceは、基本的には十分に安全だ。でも、完璧じゃない。

Nonceの強み

  • ユーザー、アクション、タイムスタンプから生成される
  • 推測するのは実質的に不可能
  • 自動的にタイムアウトする(24時間)

Nonceの弱点

  • 24時間という有効期限は、若干長い
  • XSS攻撃でNonceが盗まれる可能性がある
  • 古いプラグインではNonceチェックが実装されていないことがある

Nonceを過信せず、他のセキュリティ対策と組み合わせることが大事だ。Same-Site Cookie、リファラーチェック、セキュリティプラグインなど、多層防御で守るべきだ。

Q3: CSRF攻撃を受けたかどうか、どうやって分かる?

CSRF攻撃は、痕跡が残りにくい攻撃だ。でも、いくつかの兆候がある。

確認すべきポイント

  1. ユーザーアカウントの確認
    管理画面の「ユーザー」から、見覚えのないアカウントがないかチェックする。
  2. プラグインとテーマの確認
    インストールした覚えのないプラグインやテーマがないか確認する。
  3. 投稿と固定ページの確認
    勝手に編集されたり、スパムリンクが追加されたりしていないかチェックする。
  4. 設定の確認
    サイトタイトル、パーマリンク、一般公開設定などが変更されていないか確認する。
  5. アクセスログの確認
    サーバーのアクセスログで、不審なPOSTリクエストがないかチェックする。
# 管理画面へのPOSTリクエストを確認
$ grep "POST /wp-admin" /var/log/apache2/access.log | grep -v "自分のIPアドレス"

疑わしい動作を見つけたら、すぐにパスワードを変更して、セキュリティプラグインでフルスキャンを実行しよう。

Q4: モバイルアプリからのアクセスでもCSRF対策は必要?

WordPressのモバイルアプリ(公式アプリ)を使っている場合も、CSRF対策は重要だ。

モバイルアプリは、REST APIを通じてWordPressと通信している。このREST APIにも、Nonceに相当する認証トークンが実装されているんだ。

でも、サードパーティのアプリや、カスタム開発したアプリを使っている場合は要注意だ。これらが適切なCSRF対策を実装しているか、確認が必要だ。

チェックポイント

  • アプリがOAuth認証を使っているか
  • APIリクエストに認証トークンが含まれているか
  • HTTPSで通信しているか

不安な場合は、公式のWordPressアプリを使うのが一番安全だ。

Q5: REST APIのエンドポイントもCSRF攻撃の対象になる?

なる。むしろ、REST APIは攻撃者にとって魅力的なターゲットだ。

WordPressのREST APIは、デフォルトで多くの操作が可能だ。投稿の作成、ユーザー情報の取得、コメントの投稿など。これらすべてがCSRF攻撃の対象になり得る。

REST APIのCSRF対策

WordPress 4.7以降、REST APIにはNonceチェックが組み込まれている。でも、カスタムエンドポイントを作った場合は、自分でNonceチェックを実装する必要がある。

<?php
// カスタムREST APIエンドポイントの例
add_action( 'rest_api_init', function() {
    register_rest_route( 'my-plugin/v1', '/update-settings/', array(
        'methods' => 'POST',
        'callback' => 'my_update_settings',
        'permission_callback' => function() {
            // Nonceをチェック
            return wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp_rest' );
        }
    ));
});

function my_update_settings( $request ) {
    // 設定を更新する処理
    // ...
}
?>

REST APIを使っている場合は、特にCSRF対策を意識する必要があるんだ。

まとめ:見えない攻撃にこそ、しっかりとした備えを

CSRF攻撃は、派手じゃない。SQLインジェクションみたいに、ドラマチックな攻撃シーンがあるわけじゃない。でも、だからこそ危険なんだ。

気づかないうちに、あなたの権限で不正な操作が実行される。管理者アカウントが作られ、プラグインがインストールされ、設定が変更される。そして、被害に気づいた時には、もう手遅れになっていることが多い。

この記事のポイントをおさらいしよう:

  • CSRF攻撃は、ユーザーの信頼を悪用して不正な操作を実行させる
  • WordPressにはNonceというCSRF対策が組み込まれているが、完璧ではない
  • Same-Site Cookie、リファラーチェック、セキュリティプラグインなどで多層防御を構築する
  • プラグインとテーマは、信頼できるものだけを使い、常に最新版に保つ
  • ユーザー教育も重要。ログアウトの習慣、怪しいリンクを避ける意識を持つ

CSRF攻撃から完全に守ることはできない。でも、リスクを最小限に抑えることはできる。技術的な対策と、日々の運用の両方が大事なんだ。

僕が最初に話したクライアントは、その後、セキュリティ対策を徹底して、二度と同じ被害には遭っていない。Same-Site Cookie、セキュリティプラグイン、そしてログアウトの習慣。これらを組み合わせることで、サイトは格段に安全になった。

あなたのサイトも、今日からCSRF対策を見直してみてほしい。見えない攻撃だからこそ、見える対策で備えよう。

WordPressのセキュリティ、不安に思っていませんか?

WordPressセキュリティ診断

「自分のサイトは大丈夫だろうか…」
「何から手をつければいいか分からない…」

もしあなたが少しでもそう感じているなら、専門家によるセキュリティ診断を受けてみることを強くお勧めします。

>> WordPressセキュリティ無料診断はこちら

上記のサイトでは、WordPressのプロがあなたのサイトの脆弱性を無料で診断してくれます。問題が見つかれば、具体的な対策方法についてもアドバイスをもらえます。手遅れになる前に、一度プロの目でチェックしてもらい、安心を手に入れましょう。

お気軽にご相談ください

お見積りへ お問い合わせへ