2026年8月19日
2026年8月19日
WordPressのサードパーティ製プラグイン・テーマの安全性を確認する方法(導入前チェックとコード点検)
WordPressのサードパーティ製プラグインやテーマの安全性は、「入手元と開発状況」「既知の脆弱性」「コードとステージング環境での挙動」の3段階で確認すると、手間を抑えながら危ないものを見分けられます。どれか1つだけでは見落としが出るため、重ねて確認するのがポイントです。この記事では、導入前に見るべき項目、脆弱性データベースの調べ方、grep・PHPCS・Plugin Check を使ったコードの点検、ステージング環境での挙動確認、導入後に続ける運用までを順に解説します。
確認の全体像
プラグインやテーマはサイトの管理者と同じ権限でPHPを実行できます。1つの不備がサイト全体の乗っ取りにつながるため、「便利そうだから入れる」前に次の順で確認します。
- 入手元と開発状況:誰が作り、今も手入れされているか
- 既知の脆弱性:過去に報告された問題が、使う予定のバージョンで修正済みか
- コードと挙動:危険な書き方や、説明にない通信・ファイル操作をしていないか
1と2は数分で終わります。3は時間がかかるので、管理画面全体に影響するもの、未ログインの訪問者からの入力を扱うもの、決済や会員情報を扱うものを優先します。
入手元と開発状況を確認する
まず入手元です。公式ディレクトリ(WordPress.org)か、開発元の公式サイト・正規のマーケットプレイスから入手します。有料プラグインを無料で配布しているサイトのファイルは、バックドアが仕込まれている例が多く、コードを確認する以前に使わないでください。
公式ディレクトリのプラグインなら、詳細ページで次の点を確認します。
- 最終更新日:長期間更新がないものは、新しいWordPressやPHPへの対応、脆弱性の修正が止まっている可能性があります。
- テスト済みのWordPressバージョン:現在のメジャーバージョンから大きく離れていないか。
- 有効インストール数とサポートフォーラム:利用者が多く、報告された不具合に開発者が返答しているか。
- 変更履歴:セキュリティ修正をきちんと記載しているか。修正内容を隠さない開発者のほうが、問題が起きたときの情報も得やすくなります。
公式ディレクトリでは、セキュリティ上の問題などで配布が停止されたプラグインのページに、停止中である旨の表示が出ます。検索結果に出てこなくなったプラグインを使い続けている場合は、詳細ページを直接開いて状態を確かめます。
市販プラグインでは、販売元の会社情報、更新履歴の公開状況、脆弱性の報告窓口があるかを見ます。報告窓口を公開している開発元は、脆弱性への対応手順を持っていることが多いです。
既知の脆弱性を調べる
WordPressのプラグインとテーマの脆弱性は、WPScan、Wordfence Intelligence、Patchstack などのデータベースで公開されています。プラグイン名やスラッグで検索し、次の点を確認します。
- 報告された脆弱性の種類と深刻度
- 修正されたバージョン(使う予定のバージョンがそれ以降か)
- 修正までにかかった期間や、未修正のまま放置された報告がないか
過去に脆弱性があること自体は珍しくありません。重視したいのは、報告から修正までの早さと、未修正の報告が残っていないかです。
すでに運用中のサイトで、入っているプラグインに既知の脆弱性がないかをまとめて調べるには、WPScan のコマンドラインツールが使えます。脆弱性の照合にはWPScanのAPIトークンが必要です。
wpscan --url https://example.com --enumerate vp --api-token your-api-token
vp は脆弱性のあるプラグインだけを表示する指定です。スキャンは外部から大量のリクエストを送るため、自分が管理するサイトにだけ実行し、他人のサイトには使わないでください。
コードを点検する
データベースに載っていない問題や、意図的に仕込まれたコードは、コードを見ないと分かりません。ステージング環境やローカルにプラグインのファイルを展開し、まず grep で注意が必要な書き方を探します。
cd wp-content/plugins/target-plugin
# 難読化やバックドアでよく使われる関数
grep -rnE "eval\(|base64_decode\(|gzinflate\(|str_rot13\(|assert\(|create_function\(" --include=*.php .
# OSコマンドの実行
grep -rnE "shell_exec\(|[^_]exec\(|system\(|passthru\(|proc_open\(|popen\(" --include=*.php .
# 権限確認が不足しやすい入口
grep -rnE "wp_ajax_nopriv_|register_rest_route|__return_true" --include=*.php .
# 外部への通信先
grep -rnE "wp_remote_(get|post|request)|curl_init" --include=*.php .
ヒットしたからといって悪意があるとは限りません。たとえば base64_decode() は画像やAPIの応答の処理にも使われます。判断の目安は次のとおりです。
- 長い意味不明な文字列を
base64_decode()やgzinflate()で戻し、その結果をeval()に渡しているものは、ほぼ悪意のあるコードです。 wp_ajax_nopriv_で登録された処理や、permission_callbackが__return_trueのRESTルートは、未ログインの誰でも呼べます。その中で設定の変更、ファイルの書き込み、データベースの更新をしていないかを読みます。- データを変更する処理で、
current_user_can()による権限確認と、check_ajax_referer()やwp_verify_nonce()によるnonceの確認があるかを見ます。 $wpdb->query()などに変数を直接埋め込み、$wpdb->prepare()を使っていない箇所は、SQLインジェクションの入口になりえます。- 外部への通信では、通信先のドメインと送っている内容を確認します。サイトのURLや管理者のメールアドレスを、説明のない宛先へ送っているものは要注意です。
PHPCSとPlugin Checkで機械的に点検する
目視だけでは量が多いので、ツールで候補を絞ります。WordPress Coding Standards(WPCS)を入れた PHP_CodeSniffer では、エスケープ漏れ、nonce の確認漏れ、サニタイズ漏れ、準備されていないSQLを検出できます。
mkdir ~/wpcs && cd ~/wpcs
echo '{}' > composer.json
composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev wp-coding-standards/wpcs
vendor/bin/phpcs --standard=WordPress-Extra \
--sniffs=WordPress.Security.EscapeOutput,WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput,WordPress.DB.PreparedSQL \
--extensions=php /path/to/wp-content/plugins/target-plugin
--sniffs でセキュリティに関係するチェックだけに絞っています。指摘の中には、別の場所でエスケープ済みの値など問題のないものも含まれるため、件数ではなく「利用者の入力がそのまま出力やSQLに届く経路があるか」を見ます。
WordPress.org のプラグインレビューチームが公開している Plugin Check プラグインも使えます。ステージング環境に入れ、WP-CLI から対象のプラグインを指定して実行します。
wp plugin install plugin-check --activate
wp plugin check target-plugin
公式ディレクトリの審査基準に沿ったチェックで、セキュリティ以外の指摘も多く出ますが、エスケープやnonceに関する指摘は優先して確認する価値があります。
ステージング環境で挙動を確認する
コードを読んだら、本番と同じ構成のステージング環境に入れて、実際の動きを確かめます。本番のデータベースを複製して使う場合は、利用者のメールアドレスなど個人情報の扱いに注意し、作業前にバックアップを取っておきます。
導入の前後で次の情報を記録し、増えたものに説明のつかないものがないかを比べます。
# 導入前に before、導入して一通り操作した後に after として保存する
STAGE=before
wp user list --role=administrator --fields=ID,user_login,user_email > users-$STAGE.txt
wp cron event list --fields=hook > cron-$STAGE.txt
wp db tables > tables-$STAGE.txt
wp option list --fields=option_name --format=csv | sort > options-$STAGE.txt
# 両方そろったら差分を見る
diff users-before.txt users-after.txt
diff tables-before.txt tables-after.txt
管理者ユーザーが勝手に増えていないか、見覚えのないcronイベントが登録されていないか、どのようなテーブルやオプションが作られたかが分かります。あわせて、wp-content/uploads にPHPファイルが作られていないか、外部への通信がどこへ向かっているかも確認します。外部通信は http_api_debug アクションでホスト名を記録すると把握できます。
導入後も続けること
安全性の確認は導入時の1回で終わりではありません。
- 更新は早めに適用します。セキュリティ修正のリリース後は、修正内容から攻撃手法が分かってしまうため、更新までの期間が短いほど安全です。
- 使っていないプラグインやテーマは、停止するだけでなく削除します。停止中でも、ファイルに直接アクセスできる作りのものは攻撃の対象になります。
- 脆弱性データベースの通知や、セキュリティプラグインの脆弱性警告を受け取れるようにしておきます。
- 公式ディレクトリのプラグインは
wp plugin verify-checksums --allで、配布元のファイルと同じかを定期的に照合できます。
まとめ
- サードパーティ製コードは、入手元と開発状況、既知の脆弱性、コードと挙動の3段階で確認します(2026年10月現在の主なツールにもとづきます)。
- 正規の配布元から入手し、最終更新日・サポート状況・変更履歴を見ます。無料配布された有料プラグインは使いません。
- WPScan・Wordfence Intelligence・Patchstack で既知の脆弱性と修正バージョンを確かめます。
- grep で難読化・コマンド実行・権限確認の不足しやすい入口を探し、PHPCS(WPCS)と Plugin Check で候補を絞ります。
- ステージング環境で導入前後の管理者ユーザー、cron、テーブル、通信先を比べ、導入後も更新・削除・照合を続けます。