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.1 | REST API 経由のリモートコード実行 |
| WordPressコア 6.8〜7.0.1 | 認証不要のSQLインジェクション |
| BackWPup 5.7.4以下 | 認証不要の格納型XSS |
| Smart Custom Fields 5.0.7以下 | 格納型XSS |
いずれも上流では修正済みで、古いまま止まっているサイトだけが晒されている状態だ。コアの2件は認証不要とリモートコード実行で、放置していい類のものではない。
運任せにしていた頃なら、たぶん気づいていなかった。