WordPressのセキュリティ対策、個人サイトでもここまでやる|多層防御でSecurity Headers「A」を取った実測記録

2026.07.07 約 11 分で読めます
4層の盾に守られたWebサイトのイラスト(WordPress多層防御のイメージ)

「個人ブログに攻撃なんて来ないだろう」。半分そう思いながら、運営中の koma-ai.jp を4層の多層防御に組み直しました。結果は、外部採点の Security Headers で「A」。この記事は、その全設定と「攻撃者から本当に見えなくなったのか」を curl で確かめた実測記録です。WordPress のセキュリティ対策を、何をどこまでやれば十分かの線引きごと持ち帰ってください。

結論: 4層に分けると迷わない

先に結論です。対策リストを上から順に潰すやり方は、途中で息切れします。わたしは「層」で考えるように変えました。1つの層が破られても、次の層で止まる構えです。

WordPress多層防御の4層構成図。外側のサーバー設定から内側のテーマPHPまで、攻撃を段階的に止める構え
4層の全体像。どれか1つに頼らないのがポイントです

WordPress のセキュリティ対策は、本体・サーバー・ネットワークを重ねる「多層防御」で設計するのが定石とされています(KUSANAGI のガイドでも同じ整理です)。わたしは個人サイトの実情に合わせて、「テーマ PHP」「プラグイン」「.htaccess」「サーバー設定」の4層に置き直しました。

よくある攻撃を、どの層で止めるか

ログイン総当たり・ユーザー名列挙・設定ファイル窃取などの攻撃と、それを止める層の対応図
攻撃の入口ごとに、担当する層が決まっていると点検しやすい

この対応表が頭にあると、「この設定は何のためだっけ」と迷子になりません。以下、内側の層から順に中身を見せます。

Tier 0: テーマ PHP でやる 7 つ

セキュリティ対策の1層目は、自作テーマの inc/security.php に集約しました。ここに置く理由は2つ。git 管理なので push すれば本番に反映されること、そしてプラグインを増やさずに済むことです。

#対策実測確認
1WP バージョン情報の隠蔽(generator 等)meta generator 出力なし
2不要な wp_head 出力の削除(rsd / wlwmanifest / shortlink など)HTML から消えた
3XML-RPC 無効化 + X-Pingback ヘッダー削除X-Pingback 出力なし
4REST API の /users を非ログイン遮断404 を実測(後述)
5?author=N のリダイレクト(ユーザー名列挙の防止)author ページから列挙不可
6ログインエラーメッセージの統一ユーザー名の存在を教えない
7セキュリティヘッダー 6 種の出力全数出力を実測(後述)

ヘッダー 6 種は HSTS・X-Frame-Options・X-Content-Type-Options・Referrer-Policy・Permissions-Policy・CSP です。基準は Mozilla Observatory の採点項目に沿わせました。CSP だけは設計判断が入るので、後半の「やらないと決めたこと」で触れます。

Tier 1: プラグインは 2 つだけ

2層目はプラグインですが、入れたのは「ログイン URL の変更」と「二要素認証(TOTP)」の 2 つだけです。変更後は標準の /wp-login.php が 404 を返すことを実測で確認しました。総当たり攻撃は、そもそも入口が見つからなければ始まりません。

プラグインの固有名は、この記事ではあえて書きません。どの防御手段を使っているか自体が攻撃側へのヒントになるためです。同機能のプラグインは複数あるので、更新が続いているものを選べば大丈夫です。

ログイン試行回数の制限プラグインは検討して、見送りました。サーバー側(Tier 3)に同じ機能があり重複するからです。プラグインは増やすほど便利になりますが、脆弱性の入口も同じだけ増えます。「その層でしかできないことだけ入れる」が判断基準でした。

Tier 2: .htaccess で機密ファイルを遮断する

3層目は .htaccess です。設定ファイルや情報が漏れるファイルへの直接アクセスを、Web サーバーの手前で断ちます。書いたのは実質これだけです。

# 機密ファイルへの直接アクセスを拒否
<FilesMatch "^(wp-config.php|xmlrpc.php|readme.html|license.txt|.htaccess|.user.ini)$">
  Require all denied
</FilesMatch>

# ディレクトリ一覧表示の無効化
Options -Indexes

加えて、アップロード置き場で PHP を実行させない設定を uploads 配下に別ファイルで置きます。万一不正なスクリプトを置かれても、動かなければ被害になりません。

# wp-content/uploads/.htaccess
<FilesMatch ".php$">
  Require all denied
</FilesMatch>

1つつまずいた点を共有します。最初 Directory ディレクティブでまとめて書こうとしたのですが、これは .htaccess では使えません(サーバーが 500 で落ちます)。ファイル単位の FilesMatch と、uploads 内への別ファイル設置に分けるのが正解でした。

実測: 攻撃者から見えなくなったことを確認する

4層目のサーバー設定(WAF・国外アクセス制限・ログイン試行制限・常時SSL)は、レンタルサーバーの管理画面でスイッチを入れるだけなので手順は省きます。大事なのはここからです。セキュリティ対策は「設定した」で終わらせず、全部の層が効いているかを外から確かめます。以下は 2026-07-07 に本番へ実際に投げた curl の生出力です。

> curl.exe -sI https://koma-ai.jp/
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Content-Security-Policy: default-src 'self'; ...(allowlist 方式)

ヘッダー 6 種が全部出ています。次に、隠したいものが本当に隠れているか。機密ファイルと API を順に叩きます。

403  /readme.html
403  /license.txt
403  /wp-config.php
403  /xmlrpc.php
403  /wp-content/uploads/      ← 一覧表示も遮断
404  /wp-json/wp/v2/users      ← ユーザー名が取れない
301  http:// → https://        ← 常時SSL

外部採点は Security Headers で「A」(2026-06-08 計測・不足ヘッダーなし)。Mozilla Observatory は 75 点で B でした。満点でない理由は意図的な判断なので、次でそのまま書きます。

もう1つ、運用の落とし穴を。国外アクセス制限は便利ですが、CI/CD を巻き込みます。わたしは GitHub Actions からテーマを自動デプロイしているため、デプロイ経路だけ制限の対象を分けました。全部 ON にして「デプロイが急に動かない」は、かなりやりがちです。

やらないと決めたこと・やり漏れていたこと

正直に書くと、この構成は満点狙いではありません。まず CSP の ‘unsafe-inline’ は許容しました。WordPress 本体が複数のインラインスクリプトを出すため、nonce 化で厳格にすると本体更新のたびに壊れるリスクを抱えます。個人運営では割に合わないと判断しました。SRI(外部スクリプトの整合性チェック)も、計測タグのハッシュが頻繁に変わるため見送りです。Observatory の減点 2 項目は、この 2 つです。

やり漏れも見つかりました。この記事のために再実測したところ、HTTP レスポンスに shortlink の Link ヘッダーが残っていました。HTML 側の shortlink は削除していたのに、ヘッダー側が漏れていた形です。実害は投稿 ID が推測しやすくなる程度ですが、「一度設定して終わり」にならない実例として、修正予定ごと残しておきます。

向かない人もいます。テーマに手を入れられない既製テーマ運用の方は、Tier 0 の一部をプラグインで代替する構成になります。層の考え方自体はそのまま使えます。

まとめ: 個人サイトでも「A」は取れる

  • セキュリティ対策はリストではなく「4層」で設計する(1つ破られても次で止める)
  • テーマ PHP(Tier 0)に集約すると、プラグインを増やさず git で管理できる
  • プラグインは「その層でしかできないもの」だけ。わたしは 2 つ
  • 設定したら終わりではなく、curl と外部採点で実測して確認する
  • やらない判断(CSP 厳格化・SRI)も、理由ごと記録すれば立派な対策

この4層の考え方は、会社のコーポレートサイトや業務システムでもそのまま通用します。運営元の NEORIVA では、Web サイト構築や業務自動化を、こうしたセキュリティ設計込みでお受けしています。「うちのサイトはどこまでやれているのか」を知りたい段階のご相談でも大丈夫です。

実測スタイルの記事は、画像の WebP 一括最適化gpt-image-2 の日本語検証でも書いています。WordPress まわりの実装は爆速開発・環境構築カテゴリにまとめています。次はサイトの導線設計(記事末尾 CTA のテーマ組み込み)を実装コードごと公開する予定です。

こま

こま

元SE × AI開発 × 業務自動化の実践者

SE 4年 + プログラミング歴 8年。業務自動化と AI 組み込み開発を仕事にしながら、現場で使えるものだけを書いています。 最新のAIの現場を発信中!!