Skip to content

プラグインの自動更新をどう扱うか(コアと同じ巻き戻り問題が未解決) #8

Description

@naokazuterada

背景

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.depignorewp/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 に記載済み。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions