PHP脆弱性「php2shell」をきっかけにWordPressを卒業した話|静的化・Cloudflare移行・DNS切り替えの実践記録

2026年10月21日、PHPの緊急脆弱性「php2shell」(CVE-2026-109618/CVE-2026-109619)の修正版が公開されました。その日、カトルセはWordPressとPHPのアップデートを「やらない」と決め、コーポレートサイトを静的HTMLに置き換えてCloudflare Pagesへ移しました。PHPが動かないサーバーには、PHPの脆弱性は届かないからです。
この記事は、その判断の理由と、実際に行った手順(静的化・Cloudflare移行・DNS切り替え・SEO対策)を、中小企業のWeb担当者が同じことを再現できる粒度でまとめた実践記録です。作業の多くはClaude(生成AI)と分担し、作業を5つの段階に分けて確認しながら進め、全体を約2時間で終えました。どの段階でも数分で元に戻せる手順を用意したうえでのことです。
- 脆弱性対応で「パッチを当てる」以外の選択肢と、その判断基準
- WordPressサイトを、URLを変えずに静的サイトへ置き換える方法
- Cloudflare PagesとVercelの違いと、コーポレートサイトにCloudflareを選んだ理由
- メールを止めずにDNS(ネームサーバー)を移す手順と、事故を防ぐ確認ポイント
- 移行で検索順位を落とさないためのリダイレクトとサイトマップの扱い
※ 本記事では、セキュリティ上の理由からサーバーのIPアドレス、アカウント名、DNSレコードの値、社内システムの名称などは伏せています。
背景:PHPの脆弱性は「パッチを当てれば終わり」ではなかった
php2shellは、ログインなしで外部からサーバー上のプログラムを実行されるおそれがある、PHPの2件の脆弱性の通称です。深刻度はCVSS v4.0で9.2(緊急)。WordPressなどのCMSを含め、Webのリクエストを処理するPHPの動かし方はすべて対象です。対象バージョン・修正版・更新手順・応急処置は、解説記事「PHPの緊急脆弱性「php2shell」とは」にまとめています。
公表された脆弱性への正攻法は、修正版(パッチ)を当てることです。しかしphp2shellでは、PHP 8.1以前にはPHP公式の修正版が出ません。当社のサイトは、まさにその前提が崩れていました。調べると、現状は次のような状態でした。
| 項目 | 状態 | 意味すること |
|---|---|---|
| サーバー | 国内の共用レンタルサーバー | OSやWebサーバーの更新は事業者任せ。PHPは利用者が版を選ぶ |
| PHP | 公式サポートが終了した7系 | 本家からの修正版はもう出ない。「当てるパッチが無い」 |
| WordPress | 数年前のメジャーバージョン | 最新版はPHPの上げ幅も大きく、テーマとプラグインの互換性が読めない |
| サイトの中身 | 新しいページ群は既に静的HTML。WordPressには「お知らせ」約77件と固定ページ・投稿が残る | 動的に動かす必要があるのはお問い合わせフォームだけ。それも外部のシステムに送信していた |
つまり「PHPを動かし続ける理由」が、もうほとんど残っていませんでした。ここから、取りうる3つの道を比べました。
選択肢A:WordPressを最新版にする(採用しなかった)
一番に思いつく対応ですが、当社は「やらない」と決めました。理由は、必要な作業量に対して、得られる安全が一時的だからです。
本気でやる場合に必要な作業
- サイト一式とデータベースのバックアップ
- 検証環境(ステージング)の用意
- WordPress本体を段階的に更新(メジャーバージョンを飛ばすとデータベースの変換で失敗しやすい)
- テーマ・プラグインの互換性確認。開発が止まったプラグインは代わりを探す
- 制作会社が作った独自テーマの修正(壊れたら自社では直せない)
- 全ページの表示確認と本番反映
採用しなかった理由
- これだけでは今回の脆弱性は塞げない。今回の問題はPHP側にあり、WordPressを上げてもPHPは古いままです。
- 維持費が続く。WordPressは本体・テーマ・プラグインがそれぞれ更新され、更新を止めた瞬間から攻撃対象になります。管理画面とログイン画面を外部に公開し続けることにもなります。
- 使っていない機能にコストを払う。新しい記事は既に別の仕組みで作っており、WordPressは「過去のお知らせを表示するだけ」の役割でした。
- 決めた日の夜には終わらない。互換性の確認に時間が読めず、その間もサイトは脆弱なままです。
選択肢B:PHPを新しいバージョンに上げる(採用しなかった)
レンタルサーバーの管理画面では、PHPのバージョンをプルダウン一つで切り替えられます。作業としては最も短く済みますが、これも見送りました。
採用しなかった理由
- 古いWordPressは新しいPHPで動かない。PHP 8系では廃止された関数や変わった挙動が多く、古い本体・テーマ・プラグインは画面が真っ白になる、管理画面に入れなくなるといった障害を起こしがちです。
- 結局、選択肢Aとセットになる。PHPを上げるにはWordPressも上げる必要があり、Aの作業量がそのまま乗ってきます。
- 切り戻しはできても、脆弱な状態に戻るだけ。不具合が出てPHPを元に戻せば、サイトは表示されても脆弱性は残ります。
AもBも「PHPとWordPressを今後も使い続ける」ことが前提です。当社は、その前提自体を外すことにしました。
意思決定:「直す」のではなく「なくす」
選んだのは、サイトを静的HTMLに置き換え、PHPを動かさない配信基盤(Cloudflare Pages)へ移す道です。攻撃される部品そのものを取り除くので、今回の脆弱性だけでなく、今後のPHP・WordPressの脆弱性もまとめて無関係になります。

| 観点 | A WordPress更新 | B PHP更新 | C 静的化+Cloudflare(採用) |
|---|---|---|---|
| 今回の脆弱性 | 解消しない | 解消(WordPressが動けば) | 解消(PHPが無い) |
| 今後の脆弱性 | 更新を続ける限り対応 | 更新を続ける限り対応 | 攻撃される部品がほぼ無い |
| 壊れるリスク | 中〜高(互換性) | 高(古いコード) | 低(仮のURLで事前に全件確認できる) |
| 切り戻し | バックアップから復元 | 管理画面で戻す | DNSを1行戻す(数分) |
| 住み続けるコスト | 本体・プラグインの更新作業+サーバー代 | 同左 | サーバー代は無料枠内。更新作業は内容の変更時のみ |
| 失うもの | なし | なし | 管理画面からの記事投稿 |
判断の決め手になった3つの問い
- サーバー側で動かす必要がある機能は何か?── お問い合わせフォームだけ。しかも送信先は既に別システムだった。
- 管理画面から記事を書く人はいるか?── 新しいページはClaudeと一緒にHTMLで作っており、管理画面は使っていなかった。
- 過去のページを捨てられるか?── 捨てられない。新しいトップから過去のお知らせへリンクしており、検索の評価もそこにある。→ 同じURLのまま静的なコピーで残すと決めた。
1と2の答えが「ほぼ無い」なら、静的化は有力な選択肢です。逆に、会員機能やEC、非エンジニアによる日々の記事更新があるサイトでは、静的化だけでは済みません。
実践①:Claudeと進める静的ページへのリプレース
静的化の要点は「今あるページを、同じURL・同じ見た目のHTMLファイルにする」ことです。作り直しではなく引っ越しと考えると、作業の大半をClaude(Claude Code)に任せられます。
手順
- 棚卸し ── 公開中のURLを全件洗い出す。サイトマップ、サーバー上のファイル、データベースの投稿一覧を突き合わせる。当社では、既存の静的記事60本超に加え、WordPress側にお知らせ約77件・固定ページ31件・投稿13件がありました。
- バックアップ ── 公開フォルダを丸ごと、データベースも書き出して社内の共有ドライブへ。脆弱性の公表中なので、WordPressの管理画面へのログインは避け、FTPとデータベースの画面で作業しました。
- 静的なコピーを作る ── ブラウザに表示されているHTMLをそのまま保存し、同じパスに置く。画像・CSS・JavaScriptも含める。
- 入れないものを決める ── 管理画面・ログインページ・XML-RPC・REST API・PHPファイル全部。初期状態のまま残っていたサンプルページやテストページもここで整理。
- 転送ルールを移す ── サーバーの設定ファイル(.htaccess)や転送プラグインにあったリダイレクトを、Cloudflare Pagesの
_redirectsファイルに写し替える。整理したページも、近いページへ転送する。 - GitHubの非公開リポジトリに入れる ── 以後の更新はすべてここから。変更履歴が残り、いつでも前の版に戻せます。
- 突き合わせチェック ── 旧サイトと新サイトで全URLの応答を比べ、404が無いか機械的に確かめる。
Claudeに任せたこと、人がやったこと
| 作業 | 担当 | ポイント |
|---|---|---|
| URLの洗い出し、ページ種別の分類 | Claude | サイトマップと実ファイルの突き合わせを自動化 |
| 静的コピーの作成、不要ファイルの除外 | Claude | 「.phpが1つも無いこと」を完了条件にした |
| 転送ルールの変換、サイトマップの作成 | Claude | 人は結果を確認するだけ |
| 全URLの突き合わせチェック | Claude | 新旧の応答コードを比較 |
| 手順書兼チェック表の作成 | Claude | 全員で同じ進捗を見られる共有ページにした |
| 各サービスへのログイン、設定の変更ボタン | 人 | 認証情報はAIに渡さない |
| 見た目の確認、切り替えの判断 | 人 | 最後の「進む/戻す」は人が決める |
実践②:配信基盤にCloudflareを選んだ理由(Vercelとの比較)
コーポレートサイトのような静的サイトなら、Cloudflare Pagesが最も無理なく経営できると判断しました。決め手は、商用でも無料で使えることと、DNS・CDN・セキュリティが1か所にまとまることです。
当社は社内システム(お問い合わせの受付など)を既にVercelで動かしており、「どちらか一方」ではなく「役割で使い分ける」結論になりました。
| 観点 | Cloudflare Pages | Vercel |
|---|---|---|
| 商用利用の無料枠 | 無料プランで商用利用可 | 無料のHobbyプランは個人・非商用に限定。企業サイトは実質有料プラン |
| 転送量 | 静的配信は実質無制限 | プランごとに上限あり。超過分は従量課金 |
| DNS | 無料のDNSを一体で提供。wwwなしのドメインも素直に向けられる | DNSは外部でも可。wwwなしは指定のAレコードで対応 |
| セキュリティ | DDoS対策、ボット対策、HTTPS強制、TLSの最低版の指定などが無料で使える | 標準でDDoS対策とHTTPS。細かいWAFは上位プラン中心 |
| 得意分野 | 静的サイトと、その前段のネットワーク全般 | Next.jsなど、サーバー処理を含むWebアプリ |
| 開発体験 | GitHub連携、プレビューURL、_redirects による転送 | GitHub連携、プレビューURL、管理画面の分かりやすさは業界屈指 |
| 当社での役割 | コーポレートサイトとDNS | 社内システム・お問い合わせ受付 |
※ 料金・上限は執筆時点の公開情報に基づく概要です。契約前に各社の公式ページで最新の条件を確かめてください。
Cloudflare Pagesの設定(静的サイトの場合)
- GitHubを接続し、対象のリポジトリだけにアクセスを許可する
- フレームワーク:なし/ビルドコマンド:空欄/出力ディレクトリ:リポジトリ直下
- 公開されると、まず
プロジェクト名.pages.devの仮のURLで表示される。本番のDNSに触る前に、このURLで全ページを確かめられるのが大きな利点 _redirectsは行数に上限がある(執筆時点で静的な転送2,000行)。大規模なサイトは事前に数えておく
実践③:DNSの切り替え ── 5つの段階に分け、約2時間で切り替える
移行で一番怖いのは、サイトではなくメールが止まることです。ドメインのDNSには、Webサイトの行き先だけでなく、メールの行き先やなりすまし防止の設定が入っているからです。そこで当社は、作業を5つの段階に分け、各段階の確認を終えてから次へ進むやり方で、作業全体を約2時間で終えました。

方針:変えるものと変えないもの
| 変える | 変えない |
|---|---|
| ネームサーバー(DNSの管理場所)をCloudflareへ | ドメインの契約先(レジストラは移管しない) |
| Webサイトの配信元をCloudflare Pagesへ | メールの行き先(DNSレコードをそっくり写す) |
| ページのURL、お問い合わせの送信先 |
ネームサーバーごと移したのは、wwwなしのドメイン(例:example.co.jp)をCloudflare Pagesに向けるには、DNSをCloudflareで管理する必要があるためです。レジストラのDNSのままだと、転送のためだけに旧サーバーを残すことになります。
段階 0棚卸し(本番に影響なし)
- レジストラで、ドメインの有効期限と自動更新を確認(移転中の期限切れを防ぐ)
- 現在のDNS設定画面を丸ごとスクリーンショットで保存
- 画面の一覧だけを信じず、実際の値を引く。Google Admin ToolboxのDigなどで、A・AAAA・MX・TXT(SPF)・DKIM・DMARC・CAAと主なサブドメインを1つずつ引き、「DNS棚卸し表」に書き込む。レンタルサーバーの「かんたん設定」で入ったレコードは、一覧に出ないことがある
- Search Consoleの所有権確認、外部ツールのドメイン認証など、社内で使っているサブドメイン・TXTを洗い出す
- メールの行き先を確定させる。旧サーバーのメールを使っているアドレスがあれば、解約前に移す計画が必要
- DNSSECが無効であることを確かめる(DSレコードが空)。有効なままネームサーバーを変えると、サイトもメールも全く引けなくなる
段階 1新しいサイトを用意(本番に影響なし)
「実践①」「実践②」のとおり、静的化したサイトをCloudflare Pagesに載せ、仮のURLで全ページを確認します。
段階 2DNSだけを移す(数分で戻せる)
- Cloudflareにドメインを追加(Freeプラン)し、自動スキャンの結果を棚卸し表と1文字ずつ照合する
- この段階では全レコードを「DNSのみ」(灰色の雲)にする。中身は今と全く同じで、管理する場所だけが変わる状態を作る
- SPFのTXTは1つだけにする(2つあるとメールが不達になる)。DKIMの長い値は末尾まで比べる
- レジストラの管理画面でネームサーバーをCloudflare指定の2つに変更。旧DNSのレコードは消さない(戻すときに使う)
- DigでNSがCloudflareになり、他の値が今までと同じであることを確認
- 社外→社内、社内→社外のメールを送り、SPF・DKIM・DMARCがPASSすることを確認。お問い合わせフォームも本番でテスト
- メールとサイトに異常が無いことを確かめてから段階3へ。慎重に進めるなら、ここで48時間ほど様子を見る(当社は確認を終えた時点で続けて段階3へ進んだ)
.jpドメインのネームサーバー情報は最大で約1日キャッシュされるため、切り替えも切り戻しも、全員に行き渡るまで時間がかかる前提で計画します。作業は、切り替え後もしばらく対応できる時間帯に行うのが安全です。
段階 3サイトを切り替える(戻すのも1行)
- 切り替え前に、今のAレコードの値を控えておく(戻すとき用)
- Cloudflare Pagesの「カスタムドメイン」でドメインをつなぐ。画面の案内に従い、旧サーバー向けのAレコードをPages向けの記録に差し替える。www付きも同じようにつなぎ、wwwなしへ301で転送
- MXやTXTなど、メール関係のレコードには触らない
- 証明書の発行を待ち(数分〜15分)、本番で全ページ・フォーム・アクセス解析・メールを確認。応答ヘッダーが Cloudflare から返っているかも見る
- 「常に HTTPS を使用」をオン、TLSの最低バージョンを1.2に
段階 4後片付け
- 当日中に旧サーバーのWordPressを止める。DNSを切り替えても、IPアドレスを直接指定すれば旧サーバーには届きます。止めない限り、古いPHPのWordPressは攻撃され続けます。解約までの間も、公開フォルダへの外部アクセスをすべて拒否する設定を入れておきましょう
- テストのために一時追加した許可設定(フォームのボット対策、送信元の許可など)を外す
- 旧サーバーの解約は後日、別途行う(当社も解約はこれから)。直前にもう一度バックアップを取り、メールで使っていないことを再確認
- 余裕があれば、Cloudflare側でDNSSECを有効にする
起こりうる事故と戻し方
| 事故 | 主な原因 | 戻し方/防ぎ方 |
|---|---|---|
| メールが届かない | MX・SPF・DKIMの写し漏れ・写し間違い | ネームサーバーを元に戻す。棚卸し表との照合で事前に防ぐ |
| サイトもメールも引けない | DNSSECが有効なままネームサーバーを変更 | ネームサーバーを戻す。段階0で無効を確認 |
| 証明書エラー | 証明書の発行待ち | 待つ。15分を超えたらAレコードを戻す |
| 一部のページが404 | 静的コピーの取りこぼし・転送漏れ | _redirects に足して再公開 |
| お問い合わせが送れない | ボット対策の対象ドメイン、送信先の許可設定 | 設定に追加(数分) |
| 旧WordPressが狙われ続ける | 旧サーバーで動いたまま | 切り替え当日に停止 |
SEOへの影響と対策
サーバー移転そのものは、URLと内容が変わらなければ検索順位にほぼ影響しません。順位を落とすのは、ページが消える(404)ことと、転送の設定ミスです。当社では次の5つを徹底しました。

- URLを変えない。過去のお知らせも含め、全ページを同じURLの静的なコピーで残す。外部からのリンクもブックマークもそのまま生きます。
- 消すページは必ず301で転送する。サンプルページや不要になったページは、内容が近いページへ「恒久的な移動」として転送。転送を設定してから消す、の順番を守ります。
- サイトマップを作り直す。WordPressが自動で出していたサイトマップは静的サイトでは生成されないため、新しい sitemap.xml を置き、旧サイトマップのURLは新しい方へ転送。Search Consoleで新しいサイトマップを送信し、古い方を削除します。
- 所有権の確認方法を確かめる。Search Consoleの確認がDNSのTXTならそのまま有効。HTMLファイルやタグで確認していた場合は、新サイトにも同じものを置く必要があります。
- 正規URLをそろえる。wwwあり/なし、http/httpsをどれか1つに統一し、他は301で転送。各ページのcanonicalも同じURLを指すようにします。
移行後2週間は、Search Consoleの「ページ」レポートで404やリダイレクトエラーが増えていないかを見続けます。
なお、静的サイトをCDNから配信すると、PHPで毎回ページを組み立てるより表示は速くなりやすく、表示速度の指標(Core Web Vitals)にはプラスに働きます。ただし、順位を上げる施策というより、「落とさない」ための移行と捉えるのが妥当です。
自社で同じことをやるためのチェックリスト
判断の前に
- 自社サイトのPHPとWordPressのバージョン、サポート期限を確認した
- サーバー側で動く必要がある機能(フォーム、会員、EC、検索)を洗い出した
- 管理画面から更新している人と頻度を確認した
移行の前に
- 公開中のURLを全件リストにした
- サイト一式とデータベースをバックアップした
- DNSレコードを全件、実際に引いて棚卸し表にした(特にMX・SPF・DKIM・DMARC)
- DNSSECが無効であることを確認した
- ドメインの有効期限と自動更新を確認した
- 新サイトを仮のURLで全件確認し、404が無い
切り替え当日とその後
- DNSの移転後、メールとサイトの動作を確かめてからサイトを切り替えた(慎重に進めるなら48時間空ける)
- メールの送受信とお問い合わせフォームを本番でテストした
- 旧サーバーのWordPressを当日中に止めた
- Search Consoleに新しいサイトマップを送信した
- 旧サーバーを解約する前に、メールで使っていないことを再確認した
脆弱性情報の点検やサイト運用の見直しを、生成AIで回したい方へ
「どのシステムが、どの版の部品を使っているか」を一覧にし、新しい脆弱性の情報と照らし合わせる。今回のような移行の判断と段取りも含めて、カトルセのAI顧問がご支援します。
よくある質問(FAQ)
まとめ
脆弱性への対応は「パッチを当てる」だけではありません。使っていない機能のために攻撃される部品を持ち続けているなら、その部品をなくすのが最も確実で、維持費も下がります。生成AIのおかげで、こうした移行は中小企業でも社内だけで現実的な工数で行えるようになりました。
カトルセでは、今回のような生成AIを使った業務の進め方を、自社で実践しながら発信しています。
関連記事
- PHPの緊急脆弱性「php2shell」とは|対象バージョン・修正版・更新手順と応急処置(2026年10月) ── 自社が対象かの確かめ方、更新手順、すぐ更新できないときの応急処置
※本記事は2026年10月22日時点の当社の作業記録と、各サービスの公開情報に基づきます。画面の名前や料金・上限は各社の変更で変わることがあるため、最新の情報は公式の発表で確認してください。
