機密パスの露出: 隠しファイルが招く重大なリスク
これは何?
機密パスの露出とは、Webサーバー上の本来公開すべきでないファイルやディレクトリが、外部から直接アクセス可能な状態になっている問題です。.env、.git、.htaccess、wp-admin、phpMyAdmin、config.phpなどのファイル・ディレクトリが、適切なアクセス制限なしに公開されていると、攻撃者は機密情報を簡単に取得できます。
開発者は「これらのファイルは隠しファイルだから問題ない」「URLを知られなければ大丈夫」と考えがちですが、これは大きな誤解です。攻撃者はGoogle Dorks(特殊な検索クエリ)や自動スキャンツールを使って、これらのファイルを系統的に探索します。
特に.envファイルには、データベースパスワード、APIキー、暗号化シークレットなど、アプリケーションの根幹を支える機密情報が平文で記載されていることが多く、これが漏洩すると全システムの侵害につながります。
なぜ重要なのか
機密パスの露出は、以下のような深刻な結果を招きます:
データベースの完全侵害: .envファイルからデータベース認証情報が漏洩すると、攻撃者は外部から直接データベースにアクセスし、全データを窃取・改ざん・削除できます。個人情報、決済情報、企業秘密など、すべてが危険にさらされます。
ソースコードの流出: .gitディレクトリが公開されていると、リポジトリ全体をダウンロードされ、ソースコード、コミット履歴、開発者の情報、削除したはずの機密データまで復元されます。これにより、他の脆弱性の発見も容易になります。
管理画面への不正アクセス: wp-admin、admin、phpMyAdminなどの管理画面パスが露出していると、ブルートフォース攻撃の標的になります。パスワードが弱い場合、管理者権限を奪取されます。
APIキーの悪用: .envに含まれるAWS、Stripe、SendGridなどのAPIキーが漏洩すると、攻撃者はあなたの名義でサービスを利用し、高額な請求が発生したり、スパムメール送信の踏み台にされたりします。
バックアップファイルの悪用: config.php.bak、.env.backup、database.sql.gzなどのバックアップファイルが公開されていると、現在の設定だけでなく、過去の機密情報まで漏洩します。
攻撃の仕組み
機密パスの探索と悪用の典型的なフロー:
1. Google Dorks による自動検索
攻撃者はGoogleの高度な検索演算子を使い、脆弱なサイトを大量に発見します:
# .envファイルが公開されているサイトを検索
inurl:.env "DB_PASSWORD"
# .gitディレクトリが公開されているサイト
inurl:.git/config
# phpMyAdminが公開されているサイト
intitle:"phpMyAdmin" inurl:"/phpmyadmin/"
# バックアップファイルの検索
inurl:config.php.bak OR inurl:.env.backup OR inurl:database.sql
# wp-config.phpのバックアップ
inurl:wp-config.php.bak OR inurl:wp-config.txt
2. 自動スキャンツール
攻撃者は自動化ツールで一般的な機密パスを総当たりでチェックします:
# Dirbusterやgobusterでの探索例
gobuster dir -u https://target.com -w common-paths.txt
# common-paths.txt の内容例:
/.env
/.git/
/.git/config
/.git/HEAD
/config.php
/config.php.bak
/.htaccess
/.htpasswd
/phpMyAdmin/
/admin/
/wp-admin/
/backup/
/database.sql
/dump.sql
/.DS_Store
/composer.json
/composer.lock
/.env.local
/.env.production
3. 機密情報の抽出
.envファイルが発見された場合の攻撃例:
# .envファイルのダウンロード
curl https://target.com/.env
# 典型的な.envの内容
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=production_db
DB_USERNAME=root
DB_PASSWORD=SuperSecret123!
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
STRIPE_SECRET_KEY=sk_live_51aBcD...
APP_KEY=base64:random_encryption_key_here
攻撃者はこれらの情報を使って:
- データベースに外部から接続
- AWSのS3バケットにアクセス
- Stripeで不正決済
- 暗号化されたデータを復号
4. .git ディレクトリからの情報復元
# .gitディレクトリ全体をダウンロード
wget -r -np -nH --cut-dirs=1 https://target.com/.git/
# リポジトリからソースコードを復元
cd .git
git checkout -- .
# コミット履歴から削除された機密情報を復元
git log --all --full-history --source --find-copies-harder --diff-filter=D
git show <commit-hash>:path/to/deleted/file
開発者が「間違えてコミットしたAPIキーを削除した」つもりでも、履歴には残っています。
実際の被害事例
Uber の AWS キー流出(2016年): Uberのエンジニアが誤ってGitHubの公開リポジトリにAWSのアクセスキーをコミット。攻撃者はこのキーを使ってS3バケットにアクセスし、5,700万人分の個人情報を窃取しました。Uberは事件を隠蔽しようとしたことで追加の批判を受け、後に1億4,800万ドルの和解金を支払いました。
Codecov の.envファイル露出(2021年): コードカバレッジツールCodecovの.envファイルが不適切に公開され、攻撃者がCI/CD環境に侵入。多数の顧客企業の認証情報が漏洩し、サプライチェーン攻撃が発生しました。
Gitlab.com の.gitディレクトリ公開(2018年): GitLabの本番環境の一部で.gitディレクトリが公開状態になっており、内部ソースコードの一部が外部から閲覧可能でした。緊急でアクセス制限を実施し、大きな被害は報告されていませんが、潜在的なリスクを露呈しました。
複数企業のphpMyAdmin露出(継続中): Shodan(IoT検索エンジン)で検索すると、常時数万件のphpMyAdminインスタンスが公開されていることが確認されます。弱いパスワードや既知の脆弱性と組み合わせることで、データベースへの不正アクセスが頻発しています。
WordPress config バックアップの大量流出(2020年): セキュリティ研究者が、wp-config.php.bakやwp-config.txtが公開されているWordPressサイトを大規模に調査。数千のサイトでデータベース認証情報が平文で露出していることが判明しました。
Nyambushでの検出内容
Nyambushのパススキャンでは、以下の機密ファイル・ディレクトリをチェックします:
設定ファイル
.env(Laravel, Node.js等の環境変数).env.local,.env.production,.env.backupconfig.php,config.php.bakwp-config.php,wp-config.php.bak,wp-config.txtdatabase.ymlsettings.py(Django)application.properties(Spring Boot)
バージョン管理
.git/(Git リポジトリ).git/config,.git/HEAD.svn/(Subversion).hg/(Mercurial)
管理画面
/admin,/administrator/wp-admin(WordPress)/phpmyadmin,/phpMyAdmin,/pma/adminer.php/.well-known/security.txt(公開が推奨されるファイルだが、存在確認)
バックアップとダンプ
database.sql,dump.sql,backup.sql*.sql.gz,*.sql.zip/backup,/backupssitemap.xml(機密ではないが、ディレクトリ構造が露見)
開発ファイル
composer.json,composer.lockpackage.json,package-lock.json.DS_Store(Mac OS)Thumbs.db(Windows).htaccess,.htpasswdphpinfo.phptest.php,debug.php
スキャン結果では、検出された各ファイルの深刻度、具体的なリスク、推奨される対策を表示します。
対策方法
1. Webサーバーでのアクセス制限
Apache (.htaccess)
# .envファイルへのアクセス禁止
<FilesMatch "^\.env">
Order allow,deny
Deny from all
</FilesMatch>
# .gitディレクトリへのアクセス禁止
<DirectoryMatch "^/.*/\.git/">
Order deny,allow
Deny from all
</DirectoryMatch>
# バックアップファイルへのアクセス禁止
<FilesMatch "\.(bak|backup|old|tmp|swp|~|sql|log)$">
Order allow,deny
Deny from all
</FilesMatch>
# 設定ファイルへのアクセス禁止
<FilesMatch "^(config|wp-config|database|settings)\.(php|yml|json|ini)">
Order allow,deny
Deny from all
</FilesMatch>
Nginx
# .env, .git, バックアップファイルへのアクセス禁止
location ~ /\.(env|git|svn|hg|htaccess|htpasswd) {
deny all;
return 404;
}
# バックアップ・一時ファイル
location ~ \.(bak|backup|old|tmp|swp|~|sql|log)$ {
deny all;
return 404;
}
# 設定ファイル
location ~ ^/(config|wp-config|database|settings)\.(php|yml|json|ini) {
deny all;
return 404;
}
# phpMyAdminへのIPアドレス制限
location /phpmyadmin {
allow 192.168.1.0/24; # 自社IPのみ許可
deny all;
}
2. アプリケーションレベルでの保護
Next.js (next.config.js)
module.exports = {
// 環境変数をクライアント側に露出させない
// NEXT_PUBLIC_ プレフィックスなしの変数はサーバー側のみ
env: {
// ❌ 悪い例
// API_KEY: process.env.API_KEY,
},
async rewrites() {
return [
// 機密パスへのアクセスを404にリダイレクト
{
source: '/.env',
destination: '/404',
},
{
source: '/.git/:path*',
destination: '/404',
},
];
},
};
Express.js
const express = require('express');
const app = express();
// 機密パスへのアクセスを禁止
app.use((req, res, next) => {
const forbiddenPaths = [
/^\/\.env/,
/^\/\.git/,
/\.bak$/,
/\.backup$/,
/config\.php$/,
];
if (forbiddenPaths.some(pattern => pattern.test(req.path))) {
return res.status(404).send('Not Found');
}
next();
});
3. .gitignore の適切な設定
# 環境変数
.env
.env.*
!.env.example
# 設定ファイル
config.php
config.local.php
wp-config.php
# バックアップ
*.bak
*.backup
*.old
*.tmp
*.swp
*~
# データベースダンプ
*.sql
*.sql.gz
*.sql.zip
dump/
# OS生成ファイル
.DS_Store
Thumbs.db
# 依存関係(必要に応じて)
node_modules/
vendor/
# ログファイル
*.log
logs/
4. デプロイ時の確認
# デプロイ前に.gitディレクトリを削除
rm -rf .git
# または、.gitを含めずにデプロイ
rsync -av --exclude='.git' --exclude='.env' ./source/ user@server:/var/www/
5. robots.txt での隠蔽は逆効果
# ❌ 悪い例: robots.txtで隠すのは逆効果
User-agent: *
Disallow: /.env
Disallow: /.git/
Disallow: /admin/
# これは「ここに機密ファイルがありますよ」と宣伝しているのと同じ
robots.txtはクローラーへの「お願い」であり、セキュリティ機能ではありません。攻撃者は必ずrobotsを確認し、Disallowされたパスを優先的に調査します。
6. 定期的なスキャン
# 自サイトのチェック(安全な方法)
curl -I https://your-site.com/.env
curl -I https://your-site.com/.git/config
# すべて404または403が返ることを確認
7. Cloudflare でのWAF設定
Cloudflareを使用している場合、Firewall Rulesで追加保護が可能:
# URI Pathに以下を含む場合、ブロック
(http.request.uri.path contains "/.env") or
(http.request.uri.path contains "/.git") or
(http.request.uri.path contains ".bak") or
(http.request.uri.path contains "/phpmyadmin")
8. 既に漏洩した場合の緊急対応
もし.envやAPIキーが漏洩したことが判明した場合:
- 即座に全認証情報をローテーション(DBパスワード、APIキー等)
- アクセスログを確認(不正アクセスの有無)
- 該当ファイルへのアクセスをブロック
- GitHub等に誤ってpushした場合は、履歴から完全削除(
git filter-branchまたはBFG Repo-Cleaner) - 影響範囲の調査とインシデント報告
# Git履歴から機密ファイルを完全削除
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch .env' \
--prune-empty --tag-name-filter cat -- --all
git push origin --force --all
まとめ
機密パスの露出は、設定ミスや認識不足によって誰にでも起こりうる問題ですが、その影響は壊滅的です。「隠しファイルだから大丈夫」「URLを知られなければ安全」という考えは危険であり、攻撃者は自動化ツールで系統的に探索します。
最低限実施すべき対策:
- Webサーバーで
.env,.git等へのアクセスを禁止 .gitignoreで機密ファイルをコミット対象から除外- デプロイ時に
.gitディレクトリを含めない - バックアップファイルをWeb公開ディレクトリに置かない
- robots.txtでの「隠蔽」は逆効果と認識
追加の推奨対策: 6. phpMyAdmin等の管理画面はIP制限 7. 定期的な自己スキャン(Nyambush等) 8. APIキーは環境変数で管理、コードに直書きしない 9. AWSのSecrets Manager等のシークレット管理サービスの活用 10. 開発環境と本番環境で異なる認証情報を使用
Nyambushの定期スキャンで、意図せず公開されているファイルを早期に発見しましょう。一度漏洩した機密情報は取り返しがつきません。予防が最善の対策です。