파일 인클루전이란?
- LFI(Local File Inclusion): 로컬 시스템의 파일을 불러오는 취약점
- RFI(Remote File Inclusion): 원격 서버의 파일을 불러오는 취약점
안전한 파일 포함 방법
1. allow_url_include 비활성화
allow_url_include = Off
allow_url_fopen = Off
2. 화이트리스트 적용
$allowed_files = [
'header.php',
'footer.php',
'sidebar.php'
];
$file = $_GET['page'] ?? '';
if (in_array($file, $allowed_files)) {
include $file;
}
3. 경로 검증
function isValidPath($path) {
$realPath = realpath($path);
$basePath = realpath(__DIR__);
return strpos($realPath, $basePath) === 0;
}
보안 강화 방법
1. 디렉토리 접근 제한
Options -Indexes
php_flag allow_url_include Off
php_flag allow_url_fopen Off
2. 파일 확장자 검증
function checkFileExtension($filename) {
$allowed = ['php', 'inc'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
return in_array($ext, $allowed);
}
3. 안전한 include 함수
function safeInclude($file) {
$file = basename($file);
$path = __DIR__ . '/includes/' . $file;
if (file_exists($path) && checkFileExtension($file)) {
return include $path;
}
return false;
}
구현 예시
1. 템플릿 시스템
class Template {
private $templates_dir;
public function __construct($dir) {
$this->templates_dir = $dir;
}
public function render($template) {
$file = $this->templates_dir . '/' . basename($template) . '.php';
if (file_exists($file)) {
include $file;
}
}
}
2. 파일 매핑 시스템
$pages = [
'home' => 'home.php',
'about' => 'about.php',
'contact' => 'contact.php'
];
$page = $_GET['page'] ?? 'home';
if (isset($pages[$page])) {
include 'pages/' . $pages[$page];
}
보안 체크리스트
- 입력값 검증
- 경로 정규화
- 접근 권한 확인
- 파일 존재 여부 확인
- 화이트리스트 사용
모니터링과 로깅
function logFileAccess($file) {
$log = date('Y-m-d H:i:s') . " - File accessed: " . $file . "\n";
error_log($log, 3, 'file_access.log');
}