.env 파일 노출 보안 문제 해결하기

프리터코더·2025년 6월 4일
0

php 문제 해결

목록 보기
63/79

.env 파일에는 데이터베이스 비밀번호, API 키 등 민감한 정보가 포함되어 있어 외부에 노출되면 심각한 보안 문제가 발생할 수 있습니다. 이를 방지하고 해결하는 방법들을 알아보겠습니다.

1. 웹서버에서 .env 파일 접근 차단

가장 기본적이고 중요한 설정입니다.

server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # .env 파일 접근 차단
    location ~ /\.env {
        deny all;
        return 404;
    }

    # 모든 숨김 파일 차단
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
}
<VirtualHost *:80>
    DocumentRoot /var/www/html
    
    # .env 파일 접근 차단
    <Files ".env">
        Require all denied
    </Files>
    
    # 모든 숨김 파일 차단
    <FilesMatch "^\.">
        Require all denied
    </FilesMatch>
</VirtualHost>

2. .htaccess를 이용한 보호

Apache 환경에서 .htaccess 파일로 보호하는 방법입니다.

# .env 파일 접근 차단
<Files ".env">
    Order allow,deny
    Deny from all
</Files>

# 추가 보안 파일들 차단
<FilesMatch "\.(env|log|ini)$">
    Order allow,deny
    Deny from all
</FilesMatch>

3. 파일 권한 설정

시스템 레벨에서 파일 권한을 제한합니다.

# .env 파일 권한 설정 (소유자만 읽기 가능)
chmod 600 .env

# 웹서버 사용자만 접근 가능하도록 설정
chown www-data:www-data .env
chmod 640 .env

4. .env 파일 위치 변경

웹 루트 밖으로 .env 파일을 이동시키는 방법입니다.

<?php
class EnvLoader {
    public static function load() {
        // 웹 루트 밖의 .env 파일 로드
        $envPath = dirname(__DIR__, 2) . '/.env';
        
        if (!file_exists($envPath)) {
            throw new Exception('.env file not found');
        }
        
        $lines = file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        
        foreach ($lines as $line) {
            if (strpos($line, '=') !== false && strpos($line, '#') !== 0) {
                list($key, $value) = explode('=', $line, 2);
                $_ENV[trim($key)] = trim($value, '"\'');
            }
        }
    }
}

EnvLoader::load();

5. 환경변수 검증 및 필터링

민감한 정보가 실수로 출력되지 않도록 검증합니다.

<?php
class EnvValidator {
    private static $sensitiveKeys = [
        'DB_PASSWORD', 'API_KEY', 'SECRET_KEY', 
        'JWT_SECRET', 'MAIL_PASSWORD'
    ];
    
    public static function validateEnv() {
        foreach (self::$sensitiveKeys as $key) {
            if (empty($_ENV[$key])) {
                throw new Exception("Required environment variable $key is missing");
            }
        }
    }
    
    public static function getSafeEnvVars() {
        $safe = [];
        foreach ($_ENV as $key => $value) {
            if (!in_array($key, self::$sensitiveKeys)) {
                $safe[$key] = $value;
            }
        }
        return $safe;
    }
}

6. .gitignore 설정

버전 관리에서 .env 파일을 제외합니다.

# 환경 설정 파일
.env
.env.local
.env.production
.env.staging

# 로그 파일
*.log

# 임시 파일
*.tmp
*.cache

7. .env 템플릿 파일 생성

개발자들이 참고할 수 있는 템플릿을 제공합니다.

# 데이터베이스 설정
DB_HOST=localhost
DB_NAME=your_database
DB_USER=your_username
DB_PASSWORD=your_password

# API 키 (실제 키로 교체 필요)
API_KEY=your_api_key_here
SECRET_KEY=your_secret_key_here

# 애플리케이션 설정
APP_ENV=production
APP_DEBUG=false

8. 런타임 보안 검사

애플리케이션 실행 시 .env 파일 노출 여부를 확인합니다.

<?php
class SecurityChecker {
    public static function checkEnvExposure() {
        $envUrl = $_SERVER['HTTP_HOST'] . '/.env';
        
        $context = stream_context_create([
            'http' => [
                'timeout' => 5,
                'method' => 'GET'
            ]
        ]);
        
        $response = @file_get_contents("http://$envUrl", false, $context);
        
        if ($response !== false && strpos($response, 'DB_PASSWORD') !== false) {
            error_log('SECURITY ALERT: .env file is publicly accessible!');
            // 관리자에게 알림 발송
            self::notifyAdmin();
        }
    }
    
    private static function notifyAdmin() {
        mail('admin@example.com', 'Security Alert', '.env file exposure detected');
    }
}

9. Docker 환경에서의 보안

Docker 컨테이너에서 환경변수를 안전하게 관리합니다.

FROM php:8.1-fpm

# .env 파일을 이미지에 포함하지 않음
COPY --chown=www-data:www-data . /var/www/html
RUN rm -f /var/www/html/.env*

# 환경변수는 런타임에 주입
ENV DB_HOST=""
ENV DB_NAME=""
ENV DB_USER=""
ENV DB_PASSWORD=""
version: '3.8'
services:
  app:
    build: .
    environment:
      - DB_HOST=database
      - DB_NAME=myapp
      - DB_USER=user
      - DB_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

10. 모니터링 및 알림 시스템

.env 파일 접근 시도를 모니터링합니다.

server {
    listen 80;
    server_name example.com;
    
    location ~ /\.env {
        access_log /var/log/nginx/env_access_attempts.log;
        deny all;
        return 404;
    }
}
#!/bin/bash
LOG_FILE="/var/log/nginx/env_access_attempts.log"

if [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then
    echo "WARNING: .env access attempts detected!"
    tail -10 "$LOG_FILE"
    
    # 관리자에게 알림
    echo "Suspicious .env access attempts detected" | \
    mail -s "Security Alert" admin@example.com
    
    # 로그 파일 초기화
    > "$LOG_FILE"
fi

이러한 보안 조치들을 종합적으로 적용하면 .env 파일 노출 위험을 크게 줄일 수 있습니다. 특히 웹서버 설정과 파일 권한 관리는 필수적으로 적용해야 하는 기본 보안 조치입니다.

profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글