WordPress サイトが改ざんされる典型的な流れは、プラグインの穴などから書き込み可能なフォルダに小さな PHP ファイルを 1 個置かれ、それが「バックドア(裏口)」として何度も悪用される、というものです。この裏口は、たとえ元の穴をふさいでも残り続けます。
この記事は、WordPress を運用している Web 担当者・制作会社向けに、その裏口を作らせない/踏み台にさせないためのサーバ設定を、nginx / Apache 別のコピペ設定としてまとめたものです。プラグインを 1 つも増やさず、サーバ側とwp-config.phpだけで完結します。
対象環境: WordPress(5.x〜6.x)/ nginx または Apache / PHP-FPM。作業前に必ずバックアップを取り、まずステージング(テスト環境)で確認してから本番に反映してください。
そもそも「ファイル権限」で何が変わるのか
Linux のファイルには「所有者・グループ・その他」ごとに読み(r)・書き(w)・実行(x)の権限があり、644や755のような 3 桁の数字で表します。WordPress で重要なのは次の 2 点です。
- Web サーバ(PHP)が書き込めるファイル・フォルダを最小限にする。書き込めない場所には、攻撃者もファイルを置けません。
-
設定ファイル
wp-config.phpは、DB のパスワードなど機密の塊なので、他人(その他ユーザ)から一切読めないようにする。
推奨する基準値は次のとおりです(WordPress 公式の「Hardening WordPress」に準拠)。
| 対象 | パーミッション | 意味 |
|---|---|---|
| ディレクトリ全般 | 755 |
所有者は読み書き実行、他は読みと一覧のみ |
| ファイル全般 | 644 |
所有者は読み書き、他は読みのみ |
wp-config.php |
640(環境により600) |
他ユーザからは読めない |
.htaccess |
644 |
777(誰でも書き込み可)は絶対に使わないでください。「アップロードできない」ときの安易な解決策として設定されがちですが、バックドアの置き場所を自ら用意することになります。
Step 1: ファイル権限を一括で正す
WordPress の設置ディレクトリ(例では/var/www/html)へ移動し、ディレクトリとファイルをまとめて基準値に戻します。findで種類ごとに分けて適用するのがポイントです。
cd /var/www/html
# ディレクトリだけ 755 に
find . -type d -exec chmod 755 {} \;
# ファイルだけ 644 に
find . -type f -exec chmod 644 {} \;
# wp-config.php だけ厳しく 640(他ユーザから読めない)
chmod 640 wp-config.php
所有者は「Web サーバの実行ユーザ(www-dataやnginxなど)」に揃えるのが基本ですが、環境により推奨が異なります。まず現状を確認します。
# 実行中の PHP-FPM / Web サーバのユーザを確認
ps aux | grep -E 'php-fpm|nginx|apache2|httpd' | grep -v grep
# 設置ディレクトリの所有者を確認
ls -la /var/www/html/wp-config.php
共有レンタルサーバなどで所有者を変更できない場合は、パーミッションを640にするだけでも「同居する他ユーザからwp-config.phpを読まれる」リスクを下げられます。
Step 2: uploads フォルダでの PHP 実行を止める(最重要)
wp-content/uploadsは、画像などをアップロードするため PHP から書き込み可能です。ここに.phpファイルを置かれても実行されなければ、ただのテキストファイルで無害になります。逆にここで PHP が実行できると、置かれた裏口がそのまま動いてしまいます。
そこで「uploads(および書き込み可能なフォルダ)では PHP を実行させない」設定を入れます。これが改ざん対策で最も効く 1 手です。
nginx の場合
サイトのserverブロック内に、.phpを処理するlocationより前に次を追加します(nginx は最長一致の正規表現が優先されます)。
# uploads 配下の PHP を実行させず 403 で拒否する
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
# キャッシュや一部プラグインが使う書き込み可能ディレクトリも同様に
location ~* /wp-content/cache/.*\.php$ {
deny all;
}
反映は設定テスト後に行います。
sudo nginx -t && sudo systemctl reload nginx
Apache の場合
wp-content/uploads/直下に、次の内容の.htaccessを新規作成します(AllowOverrideが有効な環境が前提)。
# uploads 内の PHP をすべて拒否する
<FilesMatch "\.(?:php|phtml|php3|php4|php5|php7|phps)$">
Require all denied
</FilesMatch>
AllowOverride Noneで.htaccessが無効な場合は、同じ内容を仮想ホスト設定内の<Directory /var/www/html/wp-content/uploads>ブロックに書きます。反映は次のとおりです。
sudo apachectl configtest && sudo systemctl reload apache2
Step 3: wp-config.php と機密ファイルへの直接アクセスを遮断
wp-config.phpは本来 PHP として実行され中身は表示されませんが、設定ミスやバックアップの残骸(wp-config.php.bakなど)経由で中身が漏れる事故があります。念のため Web から直接アクセスできないようにしておきます。
nginx の場合
# wp-config.php とドットファイルへの直接アクセスを拒否
location = /wp-config.php {
deny all;
}
location ~ /\.(?!well-known) {
deny all;
}
Apache の場合(サイトの.htaccessまたは vhost)
# wp-config.php への直接アクセスを拒否
<Files "wp-config.php">
Require all denied
</Files>
Step 4: 管理画面からのファイル編集を無効化する
WordPress 管理画面には「テーマ・プラグインエディター」があり、管理者権限を奪われるとブラウザ上から直接 PHP を書き換えられてしまいます。運用でコード編集を使っていなければ、wp-config.phpに 1 行足して塞ぎます。
/* テーマ/プラグインの管理画面エディターを無効化 */
define( 'DISALLOW_FILE_EDIT', true );
さらに、管理画面からのプラグイン新規インストール・更新まで止めたい厳格な運用では次も検討します(更新はwp-cliやデプロイで行う運用が前提)。
/* 管理画面からのインストール/更新も禁止(運用方法を決めてから) */
define( 'DISALLOW_FILE_MODS', true );
DISALLOW_FILE_MODSは自動更新も止まるため、更新の代替手段を用意してから入れてください。
Step 5: 設定できたか確認する
最後に、設定が効いているかを実際に確かめます。まず uploads に無害なテスト用 PHP を置いて、実行されない(=ソースが表示されない、または 403 になる)ことを確認します。
# 無害なテストファイルを作成
echo '<?php echo "exec-check"; ?>' > /var/www/html/wp-content/uploads/exectest.php
# 外部から取得して挙動を確認(exec-check と表示されたら「実行されている」= 危険)
curl -s https://example.com/wp-content/uploads/exectest.php
# 確認が済んだら必ず削除
rm /var/www/html/wp-content/uploads/exectest.php
exec-checkという文字が返ってきたら PHP が実行されているので、Step 2 を見直します。403 が返る、またはソースコードがそのまま返る(実行されていない)状態が正解です。
wp-config.phpへの直接アクセスも確認します。
# 403 Forbidden が返れば OK(200 で中身が見えたら NG)
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-config.php
パーミッションの最終確認です。wp-config.phpの「その他ユーザ」に読み権限が付いていない(末尾が---)ことを見ます。
ls -la /var/www/html/wp-config.php
# 例: -rw-r----- 1 www-data www-data ... ← 末尾 --- なら他ユーザから読めない
まとめ
- 書き込めるフォルダ(uploads/cache)で PHP を実行させないのが、改ざん対策で最も効く 1 手。
- ファイルは
644・ディレクトリは755が基準。777は使わない。wp-config.phpは640。 -
wp-config.phpへの直接アクセスを遮断し、管理画面のファイル編集はDISALLOW_FILE_EDITで無効化。 - 反映後は「uploads の PHP が実行されない」ことを実際に curl で確認する。目視の設定だけで終わらせない。
これらは一度入れれば長く効く設定です。プラグインの脆弱性そのものは別途更新でふさぐ必要がありますが(ログイン強化や更新運用は下の関連記事を参照)、本記事の設定は「万一入られても裏口を残させない」ための土台になります。
関連記事
- WordPressセキュリティ 最低限やることチェックリスト10
- 「.git」「.env」が公開されていませんか? 情報漏えいを1行で防ぐ設定
- WordPressログイン総当たり対策5選(wp-login.php保護・xmlrpc無効化)
本記事のファイル権限や公開設定の状態は、Webサイトを9つの守りでまるごと守る「サイトドック」の月次の定期健診でまとめて確認できます → https://sitedock.jp