2026年7月9日

2026年7月9日

WordPressのコメントスパムを解決する方法

はじめに

WordPressのコメント欄に毎日大量のスパムコメントが届く・Akismetプラグインを有効にしているのにスパムが通過してしまう・コメントフォームがボットに自動送信されていてサーバー負荷が高い・スパムコメントが数万件溜まってデータベースが重くなっているといった問題は、Akismetの設定不備・コメントフォームへのハニーポット未設置・comment_flood_filterの無効化・Cookieチェックの欠落が原因です。

症状・原因

  • Akismetが設定されていないかAPIキーが失効している
  • コメントフォームにCAPTCHAやハニーポットが設定されていない
  • XMLRPC経由でスパムコメントが投稿されている
  • コメント投稿にログイン不要・URL必須チェックなし

解決手順

ステップ1:スパム状況を診断する

# スパムコメントの件数を確認
wp comment list --status=spam --format=count
wp comment list --status=hold --format=count
wp comment list --status=approve --format=count

# スパムコメントのIPアドレス上位を確認
wp eval "
global \$wpdb;
\$ips = \$wpdb->get_results(
    \"SELECT comment_author_IP, COUNT(*) as cnt
     FROM {\$wpdb->comments}
     WHERE comment_approved = 'spam'
     GROUP BY comment_author_IP
     ORDER BY cnt DESC
     LIMIT 10\"
);
foreach (\$ips as \$row) {
    echo \$row->comment_author_IP . ': ' . \$row->cnt . ' spam comments' . PHP_EOL;
}
"

# Akismetの設定状態を確認
wp eval "
echo 'Akismet active: '    . (is_plugin_active('akismet/akismet.php') ? 'yes' : 'no') . PHP_EOL;
echo 'Akismet API key: '   . (get_option('wordpress_api_key') ? 'set' : 'NOT SET') . PHP_EOL;
echo 'Comment status: '    . get_option('default_comment_status') . PHP_EOL;
echo 'Comment moderation: '. get_option('comment_moderation') . PHP_EOL;
echo 'Comment whitelist: ' . get_option('comment_whitelist') . PHP_EOL;
"

ステップ2:スパムコメントをクリーンアップする

# 全スパムコメントを削除
wp comment delete $(wp comment list --status=spam --format=ids) --force

# または一括削除(大量の場合)
wp eval "
global \$wpdb;
\$deleted = \$wpdb->query(
    \"DELETE FROM {\$wpdb->comments} WHERE comment_approved = 'spam'\"
);
// 孤立したコメントメタも削除
\$wpdb->query(
    \"DELETE pm FROM {\$wpdb->commentmeta} pm
     LEFT JOIN {\$wpdb->comments} c ON c.comment_ID = pm.comment_id
     WHERE c.comment_ID IS NULL\"
);
echo 'Deleted spam comments: ' . \$deleted . PHP_EOL;
"

# データベースを最適化
wp db optimize

# 古いスパムコメントを定期削除するスケジュールを設定
wp eval "
if (!wp_next_scheduled('cleanup_spam_comments')) {
    wp_schedule_event(time(), 'daily', 'cleanup_spam_comments');
    echo 'Daily spam cleanup scheduled' . PHP_EOL;
}
"

ステップ3:コメントフォームにスパム対策を追加する

// functions.php: ハニーポットフィールドを追加(ボット対策)
add_action('comment_form_after_fields', function(): void {
    ?>
    <p style="display:none !important" aria-hidden="true">
        <label for="website2">ウェブサイト(入力しないでください)</label>
        <input type="text" name="website2" id="website2" tabindex="-1" autocomplete="off">
    </p>
    <?php
});

// ハニーポットフィールドに値がある場合はスパムとして拒否
add_filter('preprocess_comment', function(array $commentdata): array {
    if (!empty($_POST['website2'])) {
        wp_die('コメントを投稿できませんでした。', 'スパム検出', ['response' => 403]);
    }
    return $commentdata;
});

// コメント投稿時間チェック(5秒以内は自動送信とみなす)
add_action('comment_form', function(): void {
    echo '<input type="hidden" name="comment_timestamp" value="' . time() . '">';
});

add_filter('preprocess_comment', function(array $commentdata): array {
    $timestamp = (int) ($_POST['comment_timestamp'] ?? 0);
    if ($timestamp > 0 && (time() - $timestamp) < 5) {
        wp_die('コメントを送信するには5秒以上かかります。', 'スパム検出', ['response' => 403]);
    }
    return $commentdata;
});

ステップ4:コメント設定でスパムを制限する

// functions.php: コメントのスパム対策設定

// ① リンクが多いコメントをスパムとして保留
add_action('init', function(): void {
    // 2個以上のリンクを含むコメントをモデレーション待ちに
    update_option('comment_max_links', 2);

    // スパムに使われやすいキーワードをブラックリストに追加
    $blacklist = get_option('blacklist_keys', '');
    $spam_keywords = ['casino', 'viagra', 'poker', 'loan', 'insurance'];
    foreach ($spam_keywords as $kw) {
        if (!str_contains($blacklist, $kw)) {
            $blacklist .= "\n" . $kw;
        }
    }
    update_option('blacklist_keys', trim($blacklist));
});

// ② 未ログインユーザーのコメントを制限
add_filter('comment_flood_filter', function(bool $block, int $time_lastcomment, int $time_newcomment): bool {
    // 前回コメントから30秒以内の投稿をブロック
    if (($time_newcomment - $time_lastcomment) < 30) {
        return true;
    }
    return $block;
}, 10, 3);

// ③ 特定のURLパターンを含むコメントを拒否
add_filter('preprocess_comment', function(array $commentdata): array {
    $content  = $commentdata['comment_content'];
    $patterns = [
        '/\[url=/i',           // BBCode風URL
        '/href=["\']http/i',   // HTMLリンク
        '/<a\s+href/i',        // HTMLアンカー
    ];
    foreach ($patterns as $pattern) {
        if (preg_match($pattern, $content) && !is_user_logged_in()) {
            wp_die('このコメントは投稿できません。', 'スパム検出', ['response' => 403]);
        }
    }
    return $commentdata;
});

ステップ5:IPブロックと長期的なスパム対策を設定する

# スパム送信元IPをWordPressのブラックリストに追加
wp eval "
\$spam_ips = ['192.0.2.1', '198.51.100.5'];  // スパム送信元IP
\$current  = get_option('blacklist_keys', '');
foreach (\$spam_ips as \$ip) {
    if (!str_contains(\$current, \$ip)) {
        \$current .= \"\\n\" . \$ip;
    }
}
update_option('blacklist_keys', trim(\$current));
echo 'IPs added to blacklist' . PHP_EOL;
"

# 定期的なスパム削除スケジュールを設定
wp eval "
add_action('cleanup_spam_comments', function(): void {
    global \$wpdb;
    // 30日以上前のスパムコメントを削除
    \$wpdb->query(
        \"DELETE FROM {\$wpdb->comments}
         WHERE comment_approved = 'spam'
         AND comment_date < DATE_SUB(NOW(), INTERVAL 30 DAY)\"
    );
});
"
// wp-config.php または functions.php: コメント機能を完全に無効化(不要な場合)
// add_action('init', function(): void {
//     // 全投稿タイプでコメントを無効化
//     foreach (get_post_types() as $post_type) {
//         if (post_type_supports($post_type, 'comments')) {
//             remove_post_type_support($post_type, 'comments');
//             remove_post_type_support($post_type, 'trackbacks');
//         }
//     }
//     // コメントフィードを無効化
//     add_filter('feed_links_show_comments_feed', '__return_false');
// });

// functions.php: reCAPTCHA v3をコメントフォームに追加
add_action('wp_enqueue_scripts', function(): void {
    if (is_singular() && comments_open()) {
        wp_enqueue_script(
            'recaptcha',
            'https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY',
            [],
            null,
            true
        );
    }
});

注意事項

  • Akismetは商用サイトでは有料プランが必要です。無料の代替としてAntispam Beeプラグインも有効です
  • コメントを完全に無効化する前に、既存の承認済みコメントをエクスポートしてバックアップしてください。設定変更後は既存コメントも表示されなくなります
  • .htaccessでXML-RPC経由のコメント投稿をブロックすると、正規のXML-RPC利用(Jetpack等)にも影響するため注意してください

まとめ

WordPressコメントスパムの解決は①wp comment list --status=spam --format=countでスパム件数確認・スパムIPアドレス上位をDBクエリで取得・Akismet APIキーの設定状態確認、②wp comment deleteで全スパムを削除・wp db optimizeでDB最適化・wp_schedule_eventで定期クリーンアップを設定、③ハニーポットフィールドをコメントフォームに追加・コメント投稿時間チェックで5秒以内の自動送信をブロック・preprocess_commentフィルターで拒否、④comment_max_linksでリンク数制限・blacklist_keysにスパムキーワード追加・comment_flood_filterで連続投稿を30秒制限、⑤スパムIPをblacklist_keysに追加・30日以上前のスパムを定期削除・reCAPTCHA v3をコメントフォームに追加の手順で解決します。

お気軽にご相談ください

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