wp-config.phpは漏れる?情報漏洩の確認と対策

実測 に検証

wp-config.php にはデータベースのパスワードと認証キーが平文で書かれています。 「PHP が停止したらソースが配信されて漏れるのではないか」という懸念をよく聞きます。

実測した結果、その心配はほぼ不要で、代わりに別の経路が確実に漏れていました。

実測 1: PHP が止まっても漏れない

wp-config.php を直接ブラウザから叩いた結果です。

状態nginxApache
正常時200 / 0 バイト200 / 0 バイト
PHP(fpm)を停止接続不能(応答なし)200 / 0 バイト

どのケースでもソースは出てきませんでした。

  • 正常時は PHP として実行され、何も出力しないので 0 バイト
  • nginx は PHP に渡せなければ 502 / 504 を返すだけで、ファイルを代わりに配信しない
  • Apache は mod_php なので、PHP-FPM の停止とは無関係

PHP ハンドラの設定が壊れれば理屈の上では起こり得ますが、 通常の構成では起きません。心配する優先順位は低いです。

実測 2: バックアップファイルは全文が漏れる

危険なのはこちらでした。wp-config.php のコピーを置いて叩きました。 中には目印として SECRET-DO-NOT-LEAK と書いてあります。

ファイル名nginxApache
wp-config.php露出なし露出なし
wp-config.php.bak★全文露出★全文露出
wp-config.php~★全文露出★全文露出
wp-config.php.save★全文露出★全文露出
wp-config.txt★全文露出★全文露出
wp-config.inc★全文露出★全文露出

5 種類すべて、両方のサーバーで、200 で全文が返りました。

理由は単純です。.php 以外の拡張子は PHP に渡されず、 静的ファイルとしてそのまま配信されます。

どうやってこのファイルができるのか

意図的に作らなくても、普通の作業で生まれます。

  • FTP クライアントやエディタが自動でバックアップを作る~ は vi / nano、.save は nano、.bak は多くのエディタ)
  • 「念のためコピーしておこう」と wp-config.php.bak を作る
  • サーバー移行時にファイル名を変えて退避する
  • 中身を確認するために .txt に変えてブラウザで開く

最後のものは、確認のためにやった行為がそのまま漏洩になります。

実測 3: ドットファイルはサーバー設定で結果が変わる

.env を置いて叩きました。

ファイルnginxApache
.env403(拒否)★全文露出

nginx 側にはドットファイルを拒否する設定がありました。

location ~ /\.(?!well-known) { deny all; }

Apache の既定にはこの保護がありません。 レンタルサーバーは基本 Apache なので、.env.git を置くと読める可能性があります。

.htaccess 自体は Apache が保護しますが、それ以外のドットファイルは対象外です。

対策

1. バックアップファイルを Web 公開領域に置かない

いちばん効く対策です。退避するなら Web から見えない場所へ。

# 悪い: 同じディレクトリに残す
cp wp-config.php wp-config.php.bak

# 良い: 公開領域の外へ
cp wp-config.php ~/backup/wp-config.php.20260912

2. サーバー設定で拡張子を塞ぐ

Apache(.htaccess)の場合です。WordPress のブロックより前に書きます (後ろに書くとリライト規則が [L] で止まって到達しません)。

# wp-config.php 本体を直接叩かれないようにする
<Files "wp-config.php">
  Require all denied
</Files>

# バックアップ・退避ファイルを拒否する
<FilesMatch "\.(bak|save|old|orig|swp|swo|inc|txt~?)$|~$">
  Require all denied
</FilesMatch>

# ドットファイル(.env など)を拒否する
<FilesMatch "^\.">
  Require all denied
</FilesMatch>

nginx の場合です。

location ~* \.(bak|save|old|orig|swp|swo|inc)$|~$ { deny all; }
location ~ /\.(?!well-known) { deny all; }
location = /wp-config.php { deny all; }

3. 漏れたら鍵を替える

漏洩が疑われる場合、ファイルを消すだけでは不十分です。

  1. データベースのパスワードを変更し、wp-config.php を更新
  2. 認証キーとソルト(8 個の define)を再生成WordPress の生成ツールで作り直す) → 全ユーザーのログインセッションが無効になり、Cookie の偽装ができなくなる
  3. 管理者のパスワードを変更
  4. 管理者ユーザーが増えていないか確認 → 乗っ取られた・改ざんされた時の確認

認証キーの再生成を忘れると、パスワードだけ変えても 盗まれた Cookie でログインされ続けます。

設定ファイル以外に外から見えている情報(ユーザー名やバージョン)の確認は → 攻撃者から何が見えているか

自分のサイトを確認する

for f in wp-config.php.bak "wp-config.php~" wp-config.php.save wp-config.txt \
         wp-config.php.old wp-config.inc .env .git/config; do
  printf "%-24s %s\n" "$f" "$(curl -s -o /dev/null -w '%{http_code}' "https://example.com/$f")"
done

403 か 404 以外が返ったら、その場で対処が必要です。 200 が返るファイルは、検索エンジンやスキャナに既に見つかっている可能性があります。

再現手順

printf '<?php\ndefine( "DB_PASSWORD", "SECRET-DO-NOT-LEAK" );\n' > src/wp-config.php.bak
cp src/wp-config.php.bak "src/wp-config.php~"

curl -s http://localhost:8080/wp-config.php.bak    # 全文が返る
curl -s http://localhost:8082/wp-config.php.bak    # 全文が返る
curl -s http://localhost:8080/wp-config.php        # 0 バイト(安全)

rm -f src/wp-config.php.bak "src/wp-config.php~"