WordPress・プラグイン・PHPの脆弱性を早く知る方法と、続く仕組みの選び方

  • WordPress
  • PHP
  • 運用
  • セキュリティ
  • 保守

WordPress で作ったサイトは、納品した瞬間から古くなっていく。プラグインに脆弱性が見つかっても、誰かが気づいて更新しなければ放置される。

厄介なのは、気づく手段が無いのではなく、多すぎて選べていないことだった。よしあきの場合、何となくニュースを見て、何となく管理画面の更新通知を見て、それで済ませていた。つまり運任せだった。

そこで一度、手段を全部並べてから選び直した。この記事はその整理と、選んだ結果の話になる。

何を追うのか

対象は3層ある。どれか一つでも古いと穴になる。

具体例更新する人
PHPサーバーのPHPバージョンサーバー管理者
WordPress本体コアのセキュリティリリースサイト管理者
プラグイン・テーマ件数が多く、脆弱性の大半はここサイト管理者

意識から抜けやすいのはPHPだ。プラグインは管理画面に更新通知が出るが、PHPは何も言ってこない。サポートが切れても動き続けるので、気づかないまま何年も経つ。

早く知る方法にはどんなものがあるか

大きく4種類ある。それぞれ性質がまるで違う。

1. 公式の発表を直接追う

一次情報。無料で、誰でも見られる。

  • WordPress本体: 公式ニュースのセキュリティカテゴリ。RSSで取れる
  • PHP: php.net のリリース情報。セキュリティ修正かどうかの区別が付いている
  • PHPのサポート期限: バージョンごとの終了日が公開されている。EOL(サポート終了)を過ぎると修正が出なくなる

正確だが、自分から見に行かないと届かない。プラグインまではカバーされない。

2. 脆弱性データベース

プラグイン個別の脆弱性はここにしかない。主要なものは3つ。

費用API
Wordfence Intelligence無料(商用も可)あり・要トークン
WPScan一部無料あり・無料枠は小さい
Patchstack実質有料無料APIなし

網羅性は高いが、そのままでは使えない。全件が返ってくるので、自分に関係あるものを選ぶ処理が要る。

3. ダイジェスト配信を受け取る

Patchstack や Wordfence が週次でメールを配信している。登録するだけで、作るものはゼロ

ただし全プラグインが対象なので、自分が使っていないものの話が大半を占める。読み飛ばす癖がつくと意味がなくなる。

4. サイト側に仕込む

セキュリティプラグインを入れて、サイト自身に見張らせる方法。管理画面から実際に入っている構成を見るので精度は一番高い

弱点は、サイトの数だけ設定と確認が要ること。そして、管理画面に入れないサイトには使えない

受け取り方の違い

方法を分ける軸はもうひとつある。向こうから来るか、自分から取りに行くかだ。

自分から見に行く方式は、忙しい時期に必ず途切れる。よしあきは何度も途切れさせてきた。続けたいなら、向こうから来る形にするしかない。

どれを選ぶか

全部やる必要はない。むしろ全部やると続かない。選ぶ基準を3つに決めた。

平常時は黙っていること。 毎日届く通知は3日で見なくなる。異常なときだけ鳴る形でなければ、仕組みごと死ぬ。

自分に関係あるものだけに絞れること。 世の中の全プラグインの話は要らない。自分が使っている数十件だけでいい。

手間がほぼゼロで済むこと。 月1回でも「自分でやる作業」が残ると、いずれやらなくなる。

この基準で並べると、方向は決まった。

ダイジェスト配信は3つ目を満たす。何も作らずに済むので、ここから始めるのが一番早い。ただし全プラグインが対象なので2つ目が弱く、結局は自分で選り分けることになる。

データベースは2つ目を満たせるが、そのままでは1つ目を満たさない。全件が返ってくるだけなので、絞り込む処理を自分で用意しないと通知が鳴りっぱなしになる。

よしあきは後者を選んだ。手間はかかるが、一度作れば手間がゼロになるからだ。

作った仕組み

二段構えにした。

第一段: 自分用の横断ウォッチ(本命)

「自分がよく使うプラグイン」に絞った一覧を作り、そこだけをコア・PHP と一緒に毎日自動でチェックする。該当が出た日だけ通知が来て、他の日は何も来ない。

届き方はこうした。定期実行は GitHub Actions に任せ、該当が出たときだけ GitHub の Issue を立てる。あとは GitHub がメールとスマホアプリに通知を飛ばしてくれる。

チャットツールに流す案も考えたが、そのための連携設定とトークン管理が増える。すでに毎日見ているところに、追加の部品なしで届くのがよかった。自分のPCが起動しているかにも左右されない。

同じ脆弱性で毎日鳴らないよう、一度知らせたものは記録して二度目は黙るようにしてある。

一覧を作るとき、記憶に頼らなかったのが効いた。手元の開発環境を全部走査して、これまでに入れたことのあるプラグインを機械的に抜き出したら67件あった。手で書き出した候補の6倍以上だ。当たり前に入れすぎて意識から消えていたものが、そのぶん放置もされやすい。

最初は「2サイト以上で使っているもの」に絞ろうとした。これは間違いだった。1サイトでしか使っていなくても、そのサイトにとっての危険度は変わらない。 実際、絞りをやめた途端に、認証不要のSQLインジェクションや、修正版がまだ出ていない脆弱性が引っかかった。どれも1サイトだけで使っていたプラグインだった。

PHPも同じ流れに乗せた。セキュリティ修正が出たときと、サポート終了が近づいたときに引っかかるようにしてある。

第二段: 相談を受けたときに、そのサイトを調べる

改修や保守の相談が来たとき、管理画面に入る前でも、公開されている情報から入っているプラグインとバージョンはある程度分かる。見つかった脆弱性は、そのまま提案と見積の根拠になる。

ただし超えられない壁がある。検出できたものが「ある」ことは言えるが、検出できなかったものが「ない」とは言えない。 管理画面でしか動かないプラグインは外から見えない。だから伝えるときは「確認できた範囲では」を必ず添える。

続けるために効いたこと

作ってみて、効いたのは技術ではなく判断のほうだった。

鳴らさないものを決める。 データベースには、修正済みの古い脆弱性も、構造上いつまでも直らない項目も混ざっている。素直に全部通すと大半が誤検知になり、通知は即死する。何を鳴らすかより、何を鳴らさないかを決めるほうが難しく、重要だった。

一覧は実測で作り、定期的に見直す。 記憶で作ると漏れる。そして使うプラグインは変わっていく。

管理外のサイトには断定しない。 言えることと言えないことの線を、毎回同じように引けるようにしておく。曖昧にすると、伝えるたびに迷うことになる。

実際に出たもの

動かし始めた初日に出たのがこれだった。

対象内容
WordPressコア 6.9〜7.0.1REST API 経由のリモートコード実行
WordPressコア 6.8〜7.0.1認証不要のSQLインジェクション
BackWPup 5.7.4以下認証不要の格納型XSS
Smart Custom Fields 5.0.7以下格納型XSS

いずれも上流では修正済みで、古いまま止まっているサイトだけが晒されている状態だ。コアの2件は認証不要とリモートコード実行で、放置していい類のものではない。

運任せにしていた頃なら、たぶん気づいていなかった。