背景
2026-07 の wp2shell(CVE-2026-63030)対応で、WordPress コアの自動更新が DISALLOW_FILE_MODS の副作用で止まっており、緊急のセキュリティ修正を受け取れず4サイトが侵害された。
コアについては次の2つで解決した。
しかし、同じ問題がプラグインでは未解決のまま残っている。
経緯: karappo/files-for-wordpress#3
問題
現状、DISALLOW_FILE_MODS = true により:
- 管理画面からのプラグインの更新・インストール・削除ができない
- プラグインの自動更新も動かない(
auto_update_plugin は明示的に __return_false にしている)
つまり プラグインのセキュリティ修正は、開発者が手元で更新してデプロイするまで一切当たらない。
WordPress サイトの侵害はコアよりプラグイン起因の方が多いため、今回コアで顕在化した構図が、より起こりやすい形で残っていることになる。
なぜ単純に自動更新を有効化できないか
プラグインも git 管理して rsync --delete で配信しているため、サーバ側で自動更新が入ると次のデプロイで古いバージョンへ巻き戻る。コアと同じ構図。
コアの巻き戻りは #4 の照合で防げるが、プラグインは照合の対象外なので、無言のうちに巻き戻る。
検討する案
案A: コアと同じ照合をプラグインにも実装する
デプロイ前にサーバ側の全プラグインのバージョンを列挙し、リポジトリ側と比較。サーバの方が新しいものがあれば中断する。
# サーバ側でのバージョン列挙(案)
for d in wp/wp-content/plugins/*/; do
f=$(grep -l -m1 "Plugin Name:" "$d"*.php 2>/dev/null | head -1)
[ -n "$f" ] && printf '%s\t%s\n' "$(basename "$d")" \
"$(grep -m1 -i '^[ *]*Version:' "$f" | sed 's/.*Version:[[:space:]]*//' | tr -d '\r')"
done
あわせて、パッチバージョンのみ自動更新するフィルタを karappo-common に入れる(WordPress にはプラグインの major/minor/patch を区別する標準機能が無いため自前実装が必要)。
add_filter('auto_update_plugin', function ($update, $item) {
$installed = get_plugins()[$item->plugin]['Version'] ?? null;
if (!$installed) return $update;
$a = explode('.', $installed);
$b = explode('.', $item->new_version);
return ($a[0] ?? '') === ($b[0] ?? '') && ($a[1] ?? '') === ($b[1] ?? '');
}, 10, 2);
課題:
- FTP のみのサーバでは実質不可能(www.fukunaga-print.co.jp が該当)。lftp で全プラグインのメインファイルを取得するのは現実的でない
- 中断が頻発する。コアの更新は年数回だが、プラグインは月に何度も更新される。パッチのみに絞っても頻度は高い。「またか」と
DEP_WP_SKIP_VERSION_CHECK=1 を常用するようになれば仕組みが形骸化する
- プラグイン数 × ファイル走査でデプロイ時間が延びる
案B: プラグインを git 管理から外す(根本解決)
.gitignore と .depignore に wp/wp-content/plugins/ を追加し、サーバ側で自由に更新させる。
利点:
- 巻き戻りが原理的に起きないので、照合も不要
- 自動更新をそのまま有効にできる(
DISALLOW_FILE_MODS も外せる)
- リポジトリが軽くなる
課題:
- プラグイン構成がリポジトリから見えなくなる(何がどのバージョンで入っているか git で追えない)
- 新規プラグインの追加・環境間の同期が手動になる
- ローカル環境の構築手順が増える
- 既存の全サイトに適用するには移行作業が必要
一般的な WordPress 運用(あるいは Composer 管理)に寄せる方向。
案C: 検知のみ
自動更新はせず、更新があることを定期的に検知して通知(issue 化 / Slack)。当てるのは従来通り手動。
利点: 低コスト、既存の運用を変えない
課題: 結局「開発者が対応するまで当たらない」問題は解決しない
論点
- 対象サイト数が多く(karappo 管理の WordPress は40件超)、どの案でも移行コストがかかる
- サイトごとに事情が違う(SSH/FTP、Sage 系/通常テーマ、稼働中/ほぼ更新なし)ため、一律の方針にできない可能性
- 「クライアントに管理画面から触らせない」という元々の意図をどこまで維持するか
補足: niwa-archives.org の特殊事情
参照している karappo-common が古い(a537036)ため DISALLOW_FILE_MODS が定義されておらず、管理画面からプラグインを更新できる状態にある。結果として 2026-07-17 の緊急自動更新も受け取れており、wp2shell の被害を免れた。
サブモジュールを最新に更新すると DISALLOW_FILE_MODS が新たに効いて運用が変わるため、本 issue の方針が決まるまで更新しない。この注意点は karappo/niwa-archives.org の README.md に記載済み。
背景
2026-07 の wp2shell(CVE-2026-63030)対応で、WordPress コアの自動更新が
DISALLOW_FILE_MODSの副作用で止まっており、緊急のセキュリティ修正を受け取れず4サイトが侵害された。コアについては次の2つで解決した。
file_mod_allowedフィルタでコアの自動更新のみ解禁しかし、同じ問題がプラグインでは未解決のまま残っている。
経緯: karappo/files-for-wordpress#3
問題
現状、
DISALLOW_FILE_MODS = trueにより:auto_update_pluginは明示的に__return_falseにしている)つまり プラグインのセキュリティ修正は、開発者が手元で更新してデプロイするまで一切当たらない。
WordPress サイトの侵害はコアよりプラグイン起因の方が多いため、今回コアで顕在化した構図が、より起こりやすい形で残っていることになる。
なぜ単純に自動更新を有効化できないか
プラグインも git 管理して
rsync --deleteで配信しているため、サーバ側で自動更新が入ると次のデプロイで古いバージョンへ巻き戻る。コアと同じ構図。コアの巻き戻りは #4 の照合で防げるが、プラグインは照合の対象外なので、無言のうちに巻き戻る。
検討する案
案A: コアと同じ照合をプラグインにも実装する
デプロイ前にサーバ側の全プラグインのバージョンを列挙し、リポジトリ側と比較。サーバの方が新しいものがあれば中断する。
あわせて、パッチバージョンのみ自動更新するフィルタを karappo-common に入れる(WordPress にはプラグインの major/minor/patch を区別する標準機能が無いため自前実装が必要)。
課題:
DEP_WP_SKIP_VERSION_CHECK=1を常用するようになれば仕組みが形骸化する案B: プラグインを git 管理から外す(根本解決)
.gitignoreと.depignoreにwp/wp-content/plugins/を追加し、サーバ側で自由に更新させる。利点:
DISALLOW_FILE_MODSも外せる)課題:
一般的な WordPress 運用(あるいは Composer 管理)に寄せる方向。
案C: 検知のみ
自動更新はせず、更新があることを定期的に検知して通知(issue 化 / Slack)。当てるのは従来通り手動。
利点: 低コスト、既存の運用を変えない
課題: 結局「開発者が対応するまで当たらない」問題は解決しない
論点
補足: niwa-archives.org の特殊事情
参照している karappo-common が古い(
a537036)ためDISALLOW_FILE_MODSが定義されておらず、管理画面からプラグインを更新できる状態にある。結果として 2026-07-17 の緊急自動更新も受け取れており、wp2shell の被害を免れた。サブモジュールを最新に更新すると
DISALLOW_FILE_MODSが新たに効いて運用が変わるため、本 issue の方針が決まるまで更新しない。この注意点は karappo/niwa-archives.org の README.md に記載済み。