2026年5月20日
2026年5月20日
WordPressのWPScanでセキュリティ検査する方法
はじめに
WPScanはWordPress専用のセキュリティスキャナーで、脆弱なプラグイン・テーマ・ユーザー列挙・設定ミスを検出します。自分のサイトを定期的にスキャンすることで、攻撃者に悪用される前に問題を発見・修正できます。
症状・原因
- プラグインやテーマに既知の脆弱性があるか確認したい
- 攻撃者の視点からサイトのセキュリティを評価したい
- ユーザー名が外部から列挙可能な状態になっている可能性がある
- 定期的な脆弱性スキャンの仕組みを作りたい
解決手順
ステップ1:WPScan をインストールする
# Ruby gem でインストール(Ruby 2.5以上が必要)
gem install wpscan
# または Docker で実行(インストール不要)
docker pull wpscanteam/wpscan
# Kali Linux / Parrot OS では標準搭載
wpscan --version
# WPScan APIトークンを取得(wpscan.com で無料登録)
# 無料プランで1日75回スキャン可能
ステップ2:基本スキャンを実行する
# 基本スキャン(サイトのセキュリティ概要)
wpscan --url https://example.com
# APIトークンを使った脆弱性データベース付きスキャン
wpscan --url https://example.com \
--api-token YOUR_API_TOKEN
# プラグインを列挙(全プラグインを検出)
wpscan --url https://example.com \
--enumerate p \
--api-token YOUR_API_TOKEN
# テーマを列挙
wpscan --url https://example.com \
--enumerate t \
--api-token YOUR_API_TOKEN
# ユーザーを列挙(ユーザー名が外部から見えるか確認)
wpscan --url https://example.com \
--enumerate u
# 全項目を包括的にスキャン
wpscan --url https://example.com \
--enumerate p,t,u,cb,dbe \
--api-token YOUR_API_TOKEN \
--output /var/log/wpscan-$(date +%Y%m%d).json \
--format json
ステップ3:検出された問題に対処する
# ユーザー列挙が可能な場合の対策
# functions.php に追加するか .htaccess で対処
# WP-CLI でユーザー名を確認
wp user list --fields=ID,user_login,user_email,roles
# REST API 経由のユーザー列挙を防ぐ
# (/wp-json/wp/v2/users が公開されている場合)
// functions.php: ユーザー列挙を防ぐ
// ① REST API のユーザー一覧エンドポイントを制限
add_filter('rest_endpoints', function(array $endpoints): array {
if (isset($endpoints['/wp/v2/users'])) {
// 未認証のリクエストにはユーザー一覧を返さない
$endpoints['/wp/v2/users'][0]['permission_callback'] = function(): bool {
return current_user_can('list_users');
};
}
if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)'])) {
$endpoints['/wp/v2/users/(?P<id>[\d]+)'][0]['permission_callback'] = function(): bool {
return current_user_can('list_users');
};
}
return $endpoints;
});
// ② author アーカイブからのユーザー名漏洩を防ぐ
add_action('template_redirect', function(): void {
if (is_author()) {
wp_redirect(home_url('/'), 301);
exit;
}
});
// ③ ログインエラーメッセージを汎用化(ユーザー名の存在を隠す)
add_filter('login_errors', function(): string {
return 'ユーザー名またはパスワードが正しくありません。';
});
ステップ4:WPScan を定期実行する自動化スクリプト
#!/bin/bash
# /usr/local/bin/wpscan-weekly.sh
# 毎週実行するスキャンスクリプト
TARGET_URL="https://example.com"
API_TOKEN="your_wpscan_api_token"
REPORT_DIR="/var/log/wpscan"
ADMIN_EMAIL="admin@example.com"
DATE=$(date +%Y%m%d)
mkdir -p $REPORT_DIR
# スキャン実行
wpscan --url $TARGET_URL \
--api-token $API_TOKEN \
--enumerate p,t,u \
--output "${REPORT_DIR}/scan-${DATE}.json" \
--format json \
--no-update 2>/dev/null
# 脆弱性があるか確認
VULNS=$(python3 -c "
import json, sys
try:
with open('${REPORT_DIR}/scan-${DATE}.json') as f:
data = json.load(f)
count = 0
for plugin in data.get('plugins', {}).values():
count += len(plugin.get('vulnerabilities', []))
for theme in data.get('main_theme', {}).get('vulnerabilities', []):
count += 1
print(count)
except:
print(0)
")
if [ "$VULNS" -gt "0" ]; then
# 脆弱性が見つかった場合はメール通知
mail -s "[警告] WPScan: ${VULNS}件の脆弱性を検出 (${DATE})" \
$ADMIN_EMAIL < "${REPORT_DIR}/scan-${DATE}.json"
fi
# 古いレポートを削除(30日以上前)
find $REPORT_DIR -name "*.json" -mtime +30 -delete
# cron に登録(毎週月曜日の午前3時に実行)
echo "0 3 * * 1 /usr/local/bin/wpscan-weekly.sh" | crontab -
ステップ5:WPScan で検出された脆弱性を修正する
# 脆弱なプラグインを一括更新
wp plugin update --all
# 特定のプラグインを更新
wp plugin update contact-form-7
# 脆弱性が修正されていない場合はプラグインを無効化
wp plugin deactivate vulnerable-plugin-name
# 脆弱なテーマを更新
wp theme update --all
# WordPress コアを更新
wp core update
wp core update-db
# 更新後に WPScan で再スキャン
wpscan --url https://example.com \
--api-token YOUR_API_TOKEN \
--enumerate p
注意事項
- WPScanは自分が管理するサイトのみスキャンしてください。他者のサイトをスキャンすることは不正アクセスとなる場合があります
- WPScan無料プランのAPIは1日75回まで。本番サイトのスキャンは週1回程度に抑え、APIを節約してください
- スキャン中はサーバーに負荷がかかります。トラフィックの少ない時間帯(深夜)に実行してください
まとめ
WPScanによるセキュリティ検査は①gem install wpscanでインストール後APIトークンを取得、②wpscan --enumerate p,t,uでプラグイン・テーマ・ユーザーを列挙、③rest_endpointsフィルターでユーザーAPIを制限・login_errorsでエラーメッセージを汎用化、④シェルスクリプト+cronで毎週自動スキャン・脆弱性検出時にメール通知、⑤検出された脆弱なプラグインをwp plugin updateで即座に更新します。