1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

技術者向け補足資料:PHPとNode.jsの脆弱性・更新・メジャーバージョンアップ ― なぜ「公開サーバーでプログラムを動かす」ことが維持負担になるのか

1
Last updated at Posted at 2026-10-24

この記事は、AIアシスタント「Muse」との朝活で、あれこれ議論しながら作りました。

― なぜ「公開サーバーでプログラムを動かす」ことが維持負担になるのか

この記事は、Web記事「ホームページに、WordPressは重すぎるのではないか」の技術者向け補足資料です。
記事本文は技術を専門としない読者向けに平易に書くことにし、こちらでは技術的な裏付けを技術者向けにまとめました。
単独でも読めます。

2026年10月21日、PHPの重大な脆弱性(いわゆるphp2shell)とNode.jsのセキュリティリリースが同日に出ました。
著者自身もNode.jsの更新対応をその日に経験しています。
その経験を出発点に、「公開サーバーでプログラムを常時動かす」という前提が、なぜ維持負担とリスクを生むのかを整理しました。

数値には出典を付けています。
単一ベンダーのデータベース等に基づく推計は、その旨を明記しました。
「悪用が観測された」と「侵入が成功した」は別の事実として扱い、混同していません。
また末尾には、この資料の性質(著者の主観も相当に混ざっていること)についての注意書きがあります。
事実関係の誤りの指摘は歓迎します。

(2026-10-25 作成)


0. 結論を先に

論点は「PHPという言語が悪い」「WordPressという製品が悪い」ではない。
論点は次の3つの掛け算である。

維持負担とリスク = 攻撃面の広さ × 公開インターネットへの露出 × 更新を続ける期間と難しさ
  • サーバーでプログラムを常時動かせば、その実行環境(PHP、Node.js、プラグイン、テーマ、依存パッケージ)の脆弱性は、匿名のインターネットからの入力で到達可能な攻撃面になる。
  • 実行環境にはサポート期限がある。期限内ならパッチで済むが、期限切れ(EOL)のあとに重大な脆弱性が出ると、残る選択肢は「ベンダーのバックポートを買う/自前で当てる」「短期間でメジャーバージョンアップをやり切る」「止める」のどれかになる。
  • メジャーバージョンアップは、後方互換のない変更、放置されたプラグイン/依存パッケージ、独自コードの書き換えと検証を伴う「プロジェクト」であって、ボタンを押す作業ではない。先送りするほど、非常時にそれを一気にやる羽目になる。
  • 逆に言えば、要件が本当にサーバー側の処理を必要とするなら、PHPでもNode.jsでも使うべきである。ただしその場合は、緊急パッチ、EOL管理、検証環境、復旧手順まで含めた運用費を、最初から見積もるべきである。
  • 要件が「お知らせと読みものを出す」だけなら、その運用費は払う必要がない。公開サーバーでプログラムを動かさない、という選択が成立する。

著者自身の今回の対応が、この対比をよく示している(§3.4、§4.1)。
公開側にPHPはインストールすらしておらず、php2shellの直撃はなかった。
使っていたNode.jsは、著者の記憶では16で、今回は22へ上げた。
16はすでにEOLのラインである。
つまりパッチではなく3世代分のメジャーバージョンアップだったが、それでもプログラムの変更は不要で、本体の入れ替えだけで済んだ。
この「メジャーを上げても壊れにくい」かどうかが、PHPとNode.jsの大きな違いとして§2.6と§3.4で扱う。


1. SNSで荒れている論争を、まず切り分ける

2026-10-21のPHP緊急リリースのあと、SNSでは大きく3つの声がぶつかっていた。

1.1 「静的HTML最強」論 ― 半分正しく、半分だけ注意が要る

象徴になったのは「阿部寛のホームページ」である。
静的HTMLだけで作られた同サイトは、当初「他のPHPサイトが緊急メンテナンスで止まる中で無事」と称賛された。
その後、同サイトも一時閲覧できなくなったが、原因はサイト自体ではなく、利用しているプロバイダがサーバー全体の安全確保のために全サイトを一括遮断した「巻き込み」だったと報じられている。

ここから引ける教訓は2つある。

  1. 自分のサイトに実行環境がなければ、その実行環境の脆弱性で自分のサイトが乗っ取られることはない。
    これは正しい。
  2. ただし静的サイトでも、置き場所(共有ホスティング、DNS、ホスティングアカウント、デプロイ経路)を共有・依存していれば、その側の停止や侵害には巻き込まれる。
    「静的=無敵」ではない。

つまり静的化は「攻撃面を消す」のであって「運用そのものを消す」のではない。
消えるのは公開面の実行環境であり、残るのは保管・配布側の管理である。
この違いを曖昧にしたまま「最強」と言うと、反論を招く。

1.2 「WordPressは悪くない/PHPは悪くない」論 ― 正しい部分を認める

この反論には、事実として正しい部分が少なくない。
先に認めておく。

  • WordPressコア自体の脆弱性は少ない。 Patchstackのデータベースでは、2025年に記録されたWordPressエコシステムの脆弱性11,334件のうち、約91%がプラグイン、約9%がテーマで、コアは6件程度とされる。※単一ベンダー(Patchstack)のデータベースに基づく集計であり、生態系全体の絶対数としてではなく「分布の偏り」を示す数字として読むべきものである。
  • 現代のPHPは遅くも雑でもない。 型、JIT、非同期基盤など、言語・実行系としての進歩は本物で、「PHP=古くて危ない言語」という言い方は乱暴である。
  • キャッシュでWordPressをほぼ静的に配信することはできる。 読み取り側の速度問題は、フルページキャッシュやCDNでかなりの程度まで解消できる。
  • マネージドホスティングや自動更新で、運用負担を肩代わりさせることはできる。 それ自体は正当な設計である。

問題は、これらの反論の多くが「まともに運用されているWordPress」を前提にしている点にある。
前提が崩れたときの姿まで含めて評価しないと、議論はすれ違う。

1.3 前提が崩れたとき何が起きるか ― 「更新すればいい」への3つの反証

  1. **更新しても直らないことがある。
    ** Patchstackの集計では、公開時点で修正パッチがまだ無い脆弱性が46%あったとされる(単一ベンダーの集計)。
    「更新すればいい」は、パッチが存在し、自分の使っているプラグインの作者がそれを出し続けている場合にだけ成立する。
  2. **更新が攻撃より遅いことがある。
    ** 同じくPatchstackの集計では、集中的に狙われた脆弱性について、公開から最初の悪用までの中央値が約5時間とされる(単一ベンダーのテレメトリ)。
    週1回の定期更新では、最初の波のあとになる。
  3. **そもそも更新先が無いことがある。
    ** 実行環境がEOLの場合である。
    これが今回いちばん大きかった問題で、§2.3で詳しく述べる。

「プラグインが悪いのであってWordPressは悪くない」という切り分けも、利用者のリスク評価としては不十分である。
WordPressの価値の中心はプラグインによる拡張性そのものであり、その拡張性を享受する以上、その供給網(作者の継続性、更新頻度、放棄の有無)ごと引き受けることになる。
コアと生態系を分けて前者だけを守っても、サイト全体の安全性は守られない。

1.4 「エンジニアの質」の話を、検証可能な形に言い換える

「危険性を判断できていないエンジニアが多いのではないか」という問題意識は、そのまま口語で出すと人への評価に聞こえ、論点がずれる。
技術資料としては、次のように検証可能な判断基準の欠如として書く方が強い。

  • そのサイトの要件に、サーバー側でしか実現できない処理が本当にあるか、選定時に切り分けたか。
  • 緊急パッチを何時間以内に当てられる体制か(担当者、権限、検証環境、切り戻し)を、契約と体制で答えられるか。
  • 実行環境とプラグインのEOL/サポート期限を一覧で管理しているか。
  • 「保守費は要らない」という前提で、常時稼働の実行環境を顧客に渡していないか。

この基準で見ると、問題は言語の好みではなく、選定と販売の仕方に寄っている。
§5で扱う。

1.5 著者の立場の出発点 ― 壊れたサイトを見ている

著者がPHP/WordPressに距離を置くのは、机上の好みではない。
数年前、仕事で関わっていた会社のWordPressサイトが侵入され、壊されるのを見ている。
その会社では本体やプラグインの更新もままならず、脆弱性が公表されるたびに危険度が上がるホームページが、その状態のまま置かれていた。

ここで著者が学んだのは「WordPressは脆い」という単純な話ではなく、更新できない状態になった動的サイトは、直す手段ごと失うという姿である。
侵入される前から、すでに詰んでいた、とも言える。

もうひとつ、著者の実務感覚として付記しておく。
ここ数年の仕事の中で、「PHPでなければ作れないプログラム」には出会っていない。
サーバー側の処理自体は、他の言語と仕組みでも実現できる。
PHP/WordPressを選ぶ理由があるとすれば、それは言語の能力そのものより、既存資産(運用中のWordPress、慣れた制作者、安い共用ホスティング、生態系の部品)といった経緯の側にあることが多い。
新規に作るなら、その経緯を持ち込むかどうかから選定を始めるべきだ、というのが著者の立場である。


2. PHP

2.1 今回の脆弱性:php2shell(2026-10-21)

2026-10-21、PHPプロジェクトは緊急セキュリティリリースを出した。

項目 内容
CVE CVE-2026-109618(OOM処理時のメモリ破壊)、CVE-2026-109619(解放済み状態の再利用)
深刻度 いずれも CVSS v4.0 で 9.2(PHPプロジェクト評価)。認証なしで到達可能とされる
修正版 PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35
影響範囲 Webリクエストを受けるPHP全般。PHP-FPM、Apache mod_php、php-cgi、FrankenPHP、LiteSpeed。最も高リスクとされるのは mod_php で、アプリケーションコードが動く前に攻撃が成立し得るとされる
性質 WordPressやプラグインの欠陥ではなく、PHP本体(リクエスト処理まわり)の問題。したがってアプリ側を最新にしていても、それだけでは塞がらない
悪用の状況 パッチ公開前に攻撃トラフィック/試行が観測されたという報告が複数ある(Cloudflare、Amazonのハニーポット等)。ただし本資料の確認範囲では「試行の観測」と「侵入成功の確認」は分けて報じられており、成功が確認されたとする公式発表は見当たらない。過度な一般化は避ける
社会側の動き 国内でも予防的な緊急メンテナンス、公的システムを含む一時停止、プロバイダによるサーバー全体の遮断などがあった

ここで重要なのは深刻度そのものより構造である。
**アプリの前に立つ層が壊れると、アプリ側の努力(本体・プラグインの更新、管理画面の防御)は、その脆弱性については無力になる。
** WordPress公式の要件ページが推奨するPHP 8.3以上に揃えていたサイトでも、修正版に上げるまでは同じ土俵にいた。

2.2 サポート期限:パッチが出る期間は決まっている

PHPの各ブランチは、完全サポート2年+セキュリティ修正のみ2年、その後EOLとなる(php.net「Supported Versions」)。

ブランチ 完全サポート終了 セキュリティ修正終了 2026-10-25時点の状態
8.5 2027-12-31 2029-12-31 サポート中
8.4 2026-12-31 2028-12-31 サポート中
8.3 2025-12-31 2027-12-31 セキュリティ修正のみ
8.2 2024-12-31 2026-12-31 セキュリティ修正のみ(残り約2か月)
8.1以下 終了 2025-12-31で終了(8.1) EOL。公式の通常リリースは出ない
  • EOL版については、今回、PHPプロジェクトが一部の旧ブランチ向けにソースレベルのバックポートを示した例はあるが、それは「自分でビルドできる人」向けの話であり、通常のホスティング利用者にとっての修正版リリースではない。実務上は、ディストリビューション/ホスティング事業者のバックポートに頼るか、ブランチを上げるしかない。
  • WordPress公式の推奨はPHP 8.3以上である。一方でWordPressはPHP 7.4以上でも「動く」。この「動く」と「支えられている」の落差が、次項の問題を生む。

2.3 いちばん重い問題:EOL世代に閉じ込められたサイト群

今回、長期停止やサービス終了の判断に至った例が目立ったのは、8.2以上を使っていたサイトではない。
PHP 5系/6(5.xの後継として内部的に扱われることがある世代表記を含む)/7系、あるいは8.1以下で長く動いてきたサイトである。
背景の数字はこうなっている。

  • WordPress.orgの統計(api.wordpress.org、2026-10-18時点を引用した集計)では、WordPressサイトのPHP版分布は、7.3以下 5.7%、7.4 16.2%、8.0 3.9%、8.1 10.8%で、**8.1以下=すでにEOLの世代だけで約36.6%**を占める。8.2も2026-12-31でEOLになるため、上げなければ年明けには過半がEOL世代になる計算である。
  • 同じ統計の生データでは、PHP 5.6だけで約1.3%、5系全体でも小さくない割合が現役で残っていると読める(二次集計による。元はWordPress.orgの統計API)。

なぜ上げられないのか。
理由は単純で、5→8や7→8は「パッチ」ではなく「移行」だからである。

  • PHPはブランチごとに移行ガイドを出し、後方互換のない変更が毎回入る。7.4→8.0では削除された関数・仕様の厳格化などが大きく、8.2では動的プロパティが非推奨に、8.4では暗黙的なnullable型が非推奨になるなど、「動いていたコードが警告を出す/止まる」変更が積み重なっている。
  • サイト側の足かせは本体より周辺にある。開発が止まったプラグイン/テーマ、旧いフレームワーク、独自コードが、特定のPHP世代にサイトを固定する。
  • 上げる作業は、バックアップ→本体・プラグインの先行更新→互換性チェック→検証環境でフォーム・決済など重要経路のテスト→切替と切り戻し準備、という手順になる。緊急時に、攻撃トラフィックが観測されている中で、これを数日でやり切るのは難しい。やり切れない場合の現実的な選択肢が「長期メンテナンス」か「終了」になる。

つまりEOL問題の本質は、「古いバージョンが危ない」という静的な話ではない。
普段は見えない移行コストが、脆弱性の公開という期限付きの非常事態で、一括で請求されることにある。
平時に少しずつ払うか、非常時にまとめて払うか、払えずに畳むか、の3択である。

2.4 パッチ更新とメジャーバージョンアップは、難易度が違う

作業 コード変更 主なコスト 失敗の仕方
同一ブランチ内のパッチ(例:8.3.x → 8.3.36) 原則なし 在庫の特定(どこでPHPが動いているか)、事業者パッケージ待ち、ワーカー再起動、動作確認 そもそもEOLでパッチが無い/事業者側の配布が遅れる
ブランチをまたぐ移行(例:7.4 → 8.3) あり得る 互換性調査、プラグイン/テーマ/独自コードの対応、検証環境での重要経路テスト、切り戻し設計 周辺部品が対応せず、サイトごと固定される

「PHPの更新は簡単だ」という言説は、上の表の1行目だけを見ている。
実務の事故はほぼ2行目で起きる。

2.5 PHPの本当の強み ― 大量リクエスト処理と、その代替

PHP/FPMの強みは認めるべきものがある。
ただし、その正体は「言語の実行速度」ではなく「実行モデル」である。

  • Shared-nothing(リクエストごとに白紙):各リクエストは状態を引き継がずに始まり、終われば解放される。状態漏れが構造的に起きにくく、1リクエストの異常が他へ波及しにくい。プログラミングモデルが単純で、水平にワーカーやサーバーを増やすだけで素直にスケールする。
  • FPMのワーカープール:Apache/Nginx+FastCGI(PHP-FPM)で、同時実行数はプロセス数で決まる。予測可能で枯れた構成であり、OPcacheでコンパイル済みコードを共有するため、短いCRUD/CMS系リクエストなら実務上十分に速い。
  • 一方、素のスループットではPHPフレームワークは上位ではない。TechEmpower Round 23の「Fortunes」系の集計では、Laravelが約16,800 RPSに対し、Node(Express)約78,000、Rust(Actix)約320,000、Go(Fiber)約338,000といった並びになる(ベンチマーク条件に強く依存するマイクロベンチマークであり、DBや外部APIが支配的な実アプリでは差は縮む。単一の集計源に基づく参考値として扱う)。

では「大量のリクエストをさばく」用途の代替は何か。
用途別に答える。

代替 向いているもの PHP-FPM比の要点 注意点
PHPのまま常駐化(FrankenPHP/RoadRunner/Swoole+Laravel Octane等) 既存PHP資産を速くしたい 起動を1回にしてオーバーヘッドを消す分、スループットは上がる(Octane系でFPM比2.5〜3倍という実測報告がある。単一ソースの実測) Shared-nothingの安全性を手放す。状態漏れ管理が新たに必要になり、実行環境の脆弱性リスク自体は残る
Node.js I/O待ちが多いAPI、WebSocket/SSEなど長い接続 イベントループで多数の接続を少ないスレッドで捌ける。素のスループットもPHPフレームワークより上 CPU仕事でイベントループが止まる。コア数分のクラスタ運用が前提になる
Go 大量処理の実務的な本命 goroutineで高い同時実行、コンパイル済み単一バイナリ、低メモリ。ベンチマーク上位常連で、開発速度と性能の釣り合いが良い PHPほどの「Webの部品の厚み」はない。チームの習熟が要る
Rust(Actix/Axum) 極端なRPS、レイテンシ、リクエスト単価が効く場所(ゲートウェイ、エッジ等) スループットとテールレイテンシは最上位圏。メモリ安全性により、C実装のメモリ破壊型バグ(まさに今回のphp2shellの類型)を言語側で減らせる 不安の所在は性能ではなく開発コスト、学習曲線、採用、変更速度。通常の業務アプリでは過剰になりやすい
C/C++(新規) ほぼ選ぶ理由がない 素の性能は出るが、メモリ安全性の負担を自前で背負う。今回のBrotli/PHPのバグがいずれもC系実装のメモリ問題であることを思えば、新規でCを選ぶのは逆向きである ―
Java/.NET 大規模業務、組織の標準基盤がある場合 ベンチマークでも上位に入り、運用の道具立てが厚い 常駐ランタイムの運用負担はPHPと同様に残る

もうひとつ、実務の順序として重要なのは、大量リクエストのボトルネックは多くの場合、言語ではなくDB・ネットワーク・外部APIだということである。
そちらが支配的なら、言語を替えても体感はほぼ変わらず、先に効くのはキャッシュ、インデックス、接続プール、キュー、CDNである。

そして著者の対象領域(お知らせと読みもののサイト)については、代替の答えは別にある。
リクエストごとに処理をする仕組みの中で最速を探すのではなく、処理自体を無くすこと、つまり静的生成+CDN配信である。
大量リクエストへの耐性という点では、どの動的ランタイムも「すでに出来上がったファイルを返す」方式には勝てない。
PHP-FPMの優秀さは動的リクエストの中での話であり、動かさなくて済む要件では、その土俵に乗らないのが最も速く、最も安く、最も安全である。

2.6 なぜ、上げなければならないのに、上げないのか

「メジャーバージョンが出たら上げるべきだ」は正論である。
それでも上がらないのには、怠慢の一言では片付かない、構造的な理由が積み重なっている。
ここを押さえないと、対策は「意識を高めよ」で終わってしまう。

  1. **上げる責任者が、契約上いない。
    ** §5の通り、「保守費なし・顧客が自分で管理できる」という売り方で納品されたサイトでは、PHPの版管理は誰の仕事でもない。
    制作会社は納品まで、ホスティング会社はサーバーの提供まで、顧客は記事の更新までが自分の範囲だと思っている。
    その隙間に、実行環境の期限管理が落ちる。
  2. **損得が非対称である。
    ** 上げて壊せば、壊した人の責任がその場で問われる。
    上げずに済ませば、事故が起きるかどうかは確率的で、起きても数年先かもしれない。
    現場のエンジニアにとって「触って壊す」リスクは具体的で、「触らずに将来乗っ取られる」リスクは抽象的である。
    この非対称がある限り、「動いているものは触らない」が個々人にとっては合理的な判断になってしまう。
  3. **費用は今・確実で、効果は将来・確率的である。
    ** 移行費用は見積もりとして今すぐ発生する。
    対して得られるものは「次の重大な脆弱性で止まらないこと」という、起きてみないと実感できない利益である。
    サイトが売上に直結しない広報物であるほど、経営側はこの費用を承認しない。
  4. **上げたくても上げられない事情が実在する。
    ** 開発の止まったプラグイン/テーマ、独自コード、検証環境もテストもない、作った人がもういない、決済や予約など外部連携が旧環境でしか保証されていない。
    こうなると移行は「上げる作業」ではなく「作り直しに近い作業」になり、さらに先送りされる。
  5. **共用環境では、最も古い1件が全体を固定する。
    ** 1台のサーバーに多数のサイトが同居する構成では、PHPの版はサイトごとに自由には選べず、最も移行できないサイトに全体が引きずられる。
  6. **先送りが自己強化する。
    ** 1世代飛ばすごとに次の移行は大きくなり、怖さも費用も増す。
    だからますます上げない。
    この悪循環の終点が、§2.3の「非常時に一括請求される」姿である。

つまり問題は、個々のエンジニアの質というより、上げることが誰の利益にもならず、上げないことの代金が先送りできる制度になっていることにある。
だからこそ提案は「ちゃんと上げよう」という精神論ではなく、「上げ続けなくて済む構成を選ぶ」「上げるなら、その費用と責任者を契約に書く」という設計と取引の話になる。

なお、この「上げない」現象はPHP固有ではない。
Node.jsでも、OpenJS財団のデータとして「利用者の約3分の2が古い版を使っている」と報じられ、EOL版のダウンロードも大量に残っている。
違いは程度と深さにある。
Nodeの古さは、活発に開発されているアプリが数世代遅れている、という形が多い。
対してPHP/WordPress側の古さは、10年以上前に作られて持ち主の関心が離れたサイトが、PHP 5系のような深い世代に残っている形を含む。
背景には、JavaScriptが「Webを壊さない」原則で機能をほぼ追加のみで進化させてきた(古い書き方が新しい実行系でも動きやすい)のに対し、PHPは世代ごとに後方互換のない変更を明確に入れてきた、という言語政策の違いもある。
もっともNodeでも、ネイティブモジュールの再ビルドや、OpenSSL 3化で古いwebpackが止まった事例のような、生態系側の破壊は起きる。
「Nodeなら崩れない」ではなく「Nodeの方が崩れる理由が言語本体より周辺に寄っている」が正確である。


3. Node.js

Node.jsを併記するのは、「PHPだけが特別に危ない」という話にしないためである。
サーバーで動かす実行環境である以上、構造は同じである。
ただし今回については、PHPと同列の危機として扱わない。
深刻度と露出条件が違う。

3.1 同日(2026-10-21)のセキュリティリリース

項目 内容
修正版 Node.js 22.23.4 / 24.22.1 / 26.12.1
件数 脆弱性10件(High 4・Medium 3・Low 3)。公式の最高深刻度は High であり、PHP側の Critical(9.2)とは一段違う
最も深刻とされるもの CVE-2026-111497:同梱Brotliデコーダの境界外書き込み。RCEに至り得ると公式が述べる。ただし到達には、攻撃者が制御できるBrotliデータをアプリが展開する経路(node:zlib での展開、fetch() で受けた応答の展開など)が必要で、「Webリクエストを受けるだけで無条件に到達する」形ではない
その他のHigh DNS名に含まれるNUL文字の切り捨て(CVE-2026-105482)、TLS証明書ホスト名検証の回避(CVE-2026-105483 / CVE-2026-106069ほか)
同梱部品の更新 Undici、c-ares、OpenSSL、SQLite、CA証明書ストア(eMudhra中間CAの信頼削除)など。本体のコードを直していなくても、同梱部品ごと入れ替わる
EOL版 Node 20以下はEOLで修正なし。公式は「セキュリティリリースの際、EOL版は常に影響を受ける」旨を明記している
悪用の状況 野外での悪用は確認されていない(2026-10-22時点)。一方で2026-10-22〜23には、Impervaのレッドチームが公式ビルド(Node.js 24.22.0、Linux arm64)上で、細工したBrotliデータによるコード実行を実験環境で実証したと報告している(成功は決定的ではなく複数回の試行を要し、対象もその構成に限られる)。つまり「実証はされたが、野外悪用は未確認」が正確な位置づけであり、PHP側の「パッチ前に攻撃トラフィックが観測された」とはここでも一段違う

3.2 ライフサイクル:こちらも期限で管理される

従来方式では半年ごとにメジャーが出て、偶数版がLTS(Current → Active LTS → Maintenance → EOL、通算約3年)になる。

ライン 2026-10-25時点の状態 EOL
22 Maintenance LTS 2027-04-30
24 Maintenance入り(2026-10-20〜) 2028-04-30
26 Current(2026-10-28にLTS入り予定) 2029-04-30
20 EOL済み 2026-04-30(終了)

なお27以降は、年1回メジャー・全版LTS化という新方式への移行が予定されている。
方式が変わっても「期限内に次のラインへ移る作業が定期的に発生する」という構造は変わらない。

3.3 更新の実務:パッチは軽いが、所在の把握が重い/メジャーは別の重さ

  • 同一ライン内のパッチは、通常はコード変更不要である。ただしプロセス再起動が要り、Dockerイメージは再ビルド、単一実行ファイル(SEA)やスナップショットで配布したものは作り直しになる。実務で手間がかかるのはバージョンを上げること自体より、「Nodeがどこで動いているか」の洗い出しである。pm2やsystemd、cron、絶対パス指定のスクリプトなど、既定バージョンを切り替えても追随しない実行単位が残りやすい、という実務報告がある。
  • メジャーバージョンアップの難所は別にある。V8の更新、ネイティブモジュールの再ビルド(NODE_MODULE_VERSIONの変更)、削除・非推奨API、Undici/fetchまわりの厳格化、依存パッケージの engines 範囲とESM/CJS問題である。
  • さらにNodeには、本体とは独立した層として npm依存パッケージ自体の脆弱性対応 がある。本体を上げても、依存ツリーの監査と更新は別作業として残る。

3.4 著者の実例:Nodeは16→22のメジャー越えでも「切り替えて起動」で済んだ

著者の使っていたNode.jsは、記憶では16で、今回22へ上げた。
16は2023年にEOLを迎えたラインであり、これはパッチではなく、18と20を飛ばす3世代分のメジャーバージョンアップである。
それでも、プログラムの変更は必要なかった。
やったことは、バージョンを切り替えて起動し、動作を確認したことであり、確認でも問題は出なかった。
著者の実感としても、今回の対応を通じて比べると、PHPの更新よりNode.jsの更新の方が断然楽で、かかった時間も、使うリソースも少なかったという。

(初稿では著者の当初の発言に基づき「使っていたのはEOLの古いラインではなかった」「パッチで済んだ」と書いていたが、その後の本人の振り返りで16→22であったため、本節はその前提で書き直した。)

この差には、偶然ではない構造的な理由がある。

  • 言語の互換性政策が違う。 JavaScriptは「Webを壊さない」を原則に、機能はほぼ追加のみで進化してきた。古い書き方は新しい実行系でもそのまま動きやすい。一方PHPは、世代ごとに後方互換のない変更を移行ガイドに明記して入れてきた(関数の削除、比較や型の扱いの変更など)。だからPHPのメジャーを上げると、コード側の点検と修正が前提になる。なおPHPには「6」が存在しない。Unicode対応を目指した6の開発が頓挫し、5の次が7になった経緯自体が、PHPのメジャー更新の難しさを象徴している。
  • 影響範囲の単位が違う。 共用サーバー/ホスティングのPHPは、1つの実行環境の上に多数のサイトが同居するのが普通である。PHPを上げれば、その上の全サイト・全プラグインの動作確認が付いて回り、しかも実施の主導権はホスティング事業者側のパッケージ配布に依存する。対してNode.jsはアプリ/コンテナごとに実行環境を持つ形が主流で、1件ずつ上げて、1件ずつ戻せる。
  • 出力の崩れ方が違う。 PHPの版を上げて互換性の問題が出ると、公開中のサイトがその場で真っ白になるなど、利用者の目に見える形で壊れる。Nodeをビルドや道具側で使う構成では、問題はビルドや起動の段階で出るため、公開前に止められる。著者の確認が「切り替えて起動して見る」で足りたのは、この性質にもよる。

留保も書いておく。
Nodeのメジャー越えが常に無事なわけではない。
ネイティブモジュールを使うアプリ、古いビルド道具(OpenSSL 3化で止まったwebpack 4の例)では、実際に壊れる。
著者の用途(スクリプトとビルド中心、ネイティブモジュール依存なし)では当たらなかった、という条件付きの事例である。
それでも、「言語本体の互換性」と「影響が公開前に出る構成」の2点で、PHPのメジャー更新より軽くなりやすいのは構造的な話である。

3.5 メジャーバージョンアップの確認方法(提案)

著者の「切り替えて起動し、確認した」を、再現できる手順にすると次のようになる。
ポイントは、本番をいきなり切り替えず、新しい版で先に試して、旧版へ戻せる状態を残すことである。

  1. 現行版の記録: node -v と依存の一覧(lockファイル)を残す。
    戻し先を確定させる。
  2. 別環境で先行実行: バージョン管理(nvm等)やコンテナで新版だけを切り替え、本番には触らない。
  3. 起動とテスト: アプリの起動、テスト、ビルドを実行する。
    エラーはこの段階で出す。
  4. ログの警告を見る: 動いても、非推奨(DeprecationWarning)の警告が出ていないか確認する。
    次のメジャーで壊れる箇所の予告である。
  5. 生成物の差分確認(静的生成の場合に特に有効): 旧版と新版でそれぞれビルドし、生成されたHTML/JSONを比較する。
    差分が無いか、あっても説明できるものだけなら、安全と判断できる根拠になる。
    実行時生成と違い、静的生成は「出力ファイルの比較」という客観的な確認ができる。
  6. 切り替えと切り戻しの用意: 問題がなければ本番の版を切り替え、旧版はしばらく残す。
    問題が出れば版を戻すだけで復旧する。

PHP/WordPress側でこの手順が重くなるのは、2と5が難しいからである。
検証環境が無く、出力がリクエストのたびに変わるため「差分が無いこと」を示しにくく、結局は目視確認の積み重ねになる。


4. 静的CMSはなぜ直撃を受けないのか ― 正直な留保を含めて

4.1 消えるもの

公開サーバーでPHPもNode.jsも動かさない構成(ビルド時に生成したHTML/JSON/画像を置くだけ)では、次が公開面から消える。

  • 実行環境の脆弱性への、匿名リクエストでの到達可能性
  • データベース、管理画面ログイン、プラグイン実行といった入口そのもの
  • 「パッチを当てるまで公開し続けるか、止めるか」という非常時の二択

今回で言えば、著者の公開サイトはPHPをインストールすらしていないため、php2shellについては当てるパッチ自体が存在しなかった。
これが「プログラムを動かさない」という前提の、最も具体的な効き方である。

4.2 消えないもの(留保)

正直に残しておく。

  • ビルド側の道具は更新が要る。 Node.js等をビルドに使う以上、その更新自体はなくならない。違うのは露出である。ビルド環境は匿名のインターネットからの入力を常時処理しないため、更新は非常対応ではなく計画作業として行える。公開面に出ていない、という一点が緊急度を変える。
  • 供給網のリスクは残る。 ビルドに使う依存パッケージに悪性のものが混ざれば、生成物が汚染され得る。生成物がファイルとして検査・差分確認でき、問題があれば前の生成物に戻せる、という性質が最後の防壁になる。
  • 置き場所のリスクは残る。 ホスティングアカウントの乗っ取り、DNS、配布経路の問題は静的でも起きる。§1.1の阿部寛サイトの例のように、共有基盤側の停止にも巻き込まれる。
  • 外部サービスを借りれば、その分だけ実行環境は戻ってくる。 コメント、フォーム受付、決済などを外部に委ねる設計では、リスクが消えるのではなく、その機能の提供者へ移る。だからこそ「全部入りを自前で常時動かす代わりに、必要な分だけ借りる」という言い方をする。

4.3 動的が必要な要件は、最初から別扱いする

静的では、前提を守る限りできないものがある。
共有する書き込み状態(コメント、会員、在庫)、秘密の強制(本人だけに見せる出し分け)、信用の要る裁定(決済確認、二重予約の防止)である。
これらが要件の中心にあるなら、実行環境を使うのが正解で、問題は「使うこと」ではなく「運用費を見積もらずに使うこと」に移る。
機能単位で分離し(その機能だけを別サービス/別サブドメインに寄せる)、サイト全体を常時実行環境の上に置かない、という中間の設計も可能である。

4.4 歴史的な先例 ― Movable Typeは「静的生成」を証明していた

「静的に書き出して配信する」という発想は新しい流行ではない。
2001年に登場したMovable Type(Perl製)は、管理側で書いた内容を「再構築」で静的HTMLに書き出して配信するモデルで一時代を作った。
著者の評価も「よくできていた」というもので、その強さは本物だった。

同時に、Movable Typeの弱さは今日の議論にそのまま効く。

  • 再構築のコスト:変更のたびに関連ページを書き直すため、サイトが大きくなるほど再構築が重くなった。コメントが付くたびにページを再構築する、という当時の姿は、対話性を動的生成で処理したくなる圧力そのものだった。この圧力に、PHPで都度生成するWordPressが応えて広がった、という経緯がある。
  • 実装言語の敷居:Perlは当時としても設置や改修の敷居が高く、利用者が手を入れるのが大変だった。元MTプロジェクト関係者の回顧でも、Perlで作られていたことが利用者の設置を難しくした点が、WordPressに流れた一因として挙げられている。著者自身の「Perlで書いてあって直すのが大変だった」という実感と重なる。
  • 残った管理側は攻撃面になる:公開ページが静的でも、管理用CGIをサーバーに置いたまま忘れれば、それは入口として残る。使われなくなった古いMovable Typeの設置残骸が脆弱性対応で無効化された、という近年の報告はその典型で、「静的配信」と「管理側の撤去」はセットでなければならないことを示している。

著者のMarkdown CMSがMovable Typeと違うのは、この3点である。
コンテンツはデータベースではなく持ち出し可能な文章ファイルであり、ビルドは手元の再構築ではなく自動化されたパイプラインが担い、公開サーバーには管理側の実行環境そのものを置かない。
再構築コストについても、正直に言えば大規模化すればビルド時間の問題は形を変えて残る。
ただしそれは「公開を止める非常事態」にはならず、ビルド側の計画課題として扱える、という違いがある。


5. なぜWordPressが選ばれてきたか ― 販売モデルの問題

技術の話だけでは、今回のEOLサイト群の量は説明できない。
供給側の経緯がある。

  • WordPressは「管理画面があるから、顧客が自分で更新できる」「だから月々の管理費は要らない」という売り方と相性が良かった。制作・営業会社が、保守契約なしの納品としてホームページを大量に作るモデルが広がった。
  • このモデルの欠陥は、コンテンツの更新責任と、実行環境の保守責任を混同したことにある。顧客が自分でできるのは記事の差し替えまでで、PHPのブランチ移行やプラグインの供給網管理は、そもそも顧客の道具立て(管理画面)の外にある。
  • 保守の担い手が契約上存在しないサイトでは、「動いているものは触らない」が合理的な判断として積み重なり、PHPの世代が固定される。§2.3の分布(EOL世代が約3割超)は、その結果の集計と読める。
  • したがって責任の所在は、個々のサイト所有者や言語そのものより先に、「保守費を払わない前提で、常時保守が必要な仕組みを渡した」販売モデルにある。静的CMSの提案は、このモデルへの対案でもある。使う人が触るのは文章だけで、裏側の保守は仕組み側が引き受けるか、そもそも保守対象を置かない。

この視点で見ると、「WordPressは悪くない」という擁護と「WordPressサイトが大量に止まった」という事実は、両立する。
製品は悪くなくても、製品に合わない売り方と運用前提で広がれば、非常時に同じ形で止まる。


6. 技術者のための選定チェックリスト(提案)

新しいサイト/作り直しで、実行環境を公開サーバーに置くかどうかは、次の順で決める。

  1. 要件の切り分け:共有する書き込み状態/秘密の強制/信用の要る裁定が、要件の中心にあるか。
    なければ静的を既定値にする。
  2. 置くなら最小化:実行環境が必要なのはサイト全体か、その機能だけか。
    機能だけなら分離できないか。
  3. 運用の見積り:緊急パッチの適用目標時間、担当と権限、検証環境、バックアップの復元テスト、EOLカレンダー(実行環境・プラグイン・依存パッケージ)を、金額と体制で書けるか。
    書けないなら、それは「運用できない」という選定結果である。
  4. 供給網の棚卸し:プラグイン/テーマ/依存パッケージの一覧、作者の更新継続、放棄された部品の有無を定期的に確認できるか。
  5. 出口の確保:コンテンツがMarkdownなど持ち出し可能な形で残るか。
    データベースの中にしか無い状態を避けられるか。
  6. 販売時の明示:「自分で更新できます」と言うとき、それがコンテンツ更新の話なのか、保守まで含むのかを分けて伝えているか。
    保守が含まれないなら、その旨と、非常時の選択肢(移行費用か終了か)を先に示す。

7. SNSの典型的な反論への短い返し(技術者向け)

  • 「PHPは悪くない」 ― その通り。ただし言語の良し悪しと、公開サーバーに置いた実行環境の露出・運用負担は別の軸である。本資料の批判は後者にだけ向いている。
  • 「WordPressは悪くない、プラグインが悪い」 ― コアの数字はその通り(§1.2)。だが利用者が引き受けるのは生態系全体であり、価値の中心である拡張性を外してWordPressを評価することはできない。
  • 「キャッシュを入れれば静的と同じ」 ― 読み取り配信は近づく。だが生成側(管理画面、PHP、データベース)は残り、今回のような本体層の脆弱性では、キャッシュの有無は到達可能性を消さない。
  • 「更新すればいいだけ」 ― パッチが存在し(§1.3-1)、攻撃より速く当てられ(§1.3-2)、EOLでない(§1.3-3)場合に限る。この3条件を常時満たす体制の費用こそが論点である。
  • 「静的は編集が大変/時代遅れ」 ― 編集体験はビルドのパイプラインの問題であり、実行環境の有無とは分離できる。Markdown+自動ビルドで、利用者が触るのは文章だけ、という形は実証済みである(対象記事参照)。動的機能が要る要件では負けを認める。その切り分けが提案の本体である。
  • 「PHPでしかできないことはPHPでやればいい」 ― 原則として同意する。ただし実務では、言語の能力として「PHPでしかできないこと」はほぼ無い。残るのは既存資産や生態系といった経緯の理由である(§1.5)。本資料の主張は「PHPを使うな」ではなく、「新規に作るのに、その経緯も無いのに、PHPの運用費だけ払い続けるな」である。既存のWordPress資産を活かす判断なら、その運用費を見積もった上でなら筋は通る。

8. 記事に使える平易な一文(候補)

記事本文側で、専門用語を使わずに本資料の要点へ橋をかけるときの候補。
本文の文体に合わせて選ぶ。

  1. 「プログラムを動かさなければ、そのプログラムの穴を突かれることもありません。」
  2. 「更新し続ける前提の仕組みを、更新する人がいないまま渡してはいけないのだと思います。」
  3. 「古いまま動かしてきたサイトほど、いちばん困ったときに、いちばん大きな直し方を迫られました。」
  4. 「掲示板を貼り替えるために発電所を維持するなら、発電所の点検費用まで含めて考える必要があります。」
  5. 「できないことがある代わりに、壊れる場所そのものを持たない、という選び方です。」
  6. 「必要な機能の分だけ借りる。
    全部入りを自前で動かし続けない。
    それだけの話です。」

出典

確認日はいずれも2026-10-25。
一次情報(公式)を優先し、二次情報にはその旨を記した。

※ 本資料で「単一ソース」と明記した推計値(Patchstack集計の脆弱性件数・割合・時間、暴露台数に関する一部報道の数字など)は、そのソースの測定範囲での数字であり、異なるデータベースでは値が変わり得る。
分布や傾向を示す用途に限って用いた。


おわりに ― この資料の性質について、読者へのお願い

最後に、この資料がどういうものかを正直に書いておきます。

この資料には、公式発表や統計で確認した事実と並んで、**著者自身の経験と主観的な見解が相当に混ざっています。
** 原体験として書いた侵入被害の目撃、今回のNode.js 16→22の更新が軽かったという実感、「保守費を払わない前提で常時稼働の実行環境を渡す販売モデルが良くなかった」という評価は、どれも著者の立場からの判断です。
事実の部分は出典を付け、単一ソースの数値にはその旨を明記しましたが、全ての記述を著者自身が一次情報まで検証し切れているわけではありません。
また、脆弱性情報やサポート期限は日々変わります。
本資料の内容は2026年10月25日時点のものです。

ですので、エンジニアの読者にお願いです。
この資料を結論として受け取るのではなく、出発点として使ってください。
ご自身の環境については、出典に挙げた公式発表や一次情報を直接確認し、ご自身で調べて、ご自身で判断してください。
そのうえで「ここの数字は違う」「この見立ては外している」という点があれば、それは著者にとっても歓迎すべき指摘です。
事実関係の誤りは、確認でき次第、訂正します。

著者の主張の核心は、特定の言語や製品への好き嫌いではありません。
「公開サーバーでプログラムを常時動かす」という前提を選ぶなら、その更新と期限管理に責任と費用が伴う。
伴わないのなら、前提そのものを変える選択肢もある。
その判断材料を並べたものとして、この資料を読んでいただければ幸いです。


この資料は、Lyre3 GamesのTechブログにも載せています。本編の記事「ホームページに、WordPressは重すぎるのではないか」も、よければどうぞ。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?