PHP 는 대부분의 서버시스템에서 파일과 디렉터리 기반의 권한에 대한 보안을 담당합니다. 이는 읽기 가능한 파일시스템에 존재하는 파일을 제어 할수 있도록 합니다. 파일시스템에 접근하는 모든 사용자에 의해 읽혀지는 파일이 안전한지 보장하기 위해 읽기 가능한 모든 파일을 신경써야 됩니다.
PHP 가 사용자 레벨의 파일시스템 접근을 허용하도록 만들어진 뒤로, /etc/passwd 파일과 같은 시스템 파일을 읽고, 이더넷을 조작하거나, 프린트 잡을 보내거나 등등의 PHP 스크립트 파일을 작성하는게 가능해 졌습니다. 이것은 다소 직접적인 영향을 미치는데, 읽으려거나 쓰려는 파일이 적절한 파일인지 확실히 할 필요가 있습니다.
다음 스크립트를 보면, 사용자의 홈디렉터리에서 파일을 지웁니다. 이때 파일관리를 위해 PHP 웹 인터페이스가 사용됨을 가정합니다. 이로 인해 Apache 사용자가 사용자 홈디렉터리 안에 있는 파일의 삭제가 가능하게 됩니다.
Example #1 공격을 유발하는 나쁜 변수 체크 방법
<?php
// 사용자의 홈디렉터리로부터 파일을 제거 합니다.
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
unlink("$homedir/$userfile");
echo "The file has been deleted!";
?>
Example #2 파일시스템 공격
<?php
// PHP 유저가 하드드라이브 내에 접근권한을 가진 파일을 삭제 합니다.
// 만약에 root 권한을 가진다면:
$username = $_POST['user_submitted_name']; // "../etc"
$userfile = $_POST['user_submitted_filename']; // "passwd"
$homedir = "/home/$username"; // "/home/../etc"
unlink("$homedir/$userfile"); // "/home/../etc/passwd"
echo "The file has been deleted!";
?>
Example #3 좀더 안전한 파일명 체크
<?php
// PHP 유저가 하드드라이브 내에 접근권한을 가진 파일을 삭제 합니다.
$username = $_SERVER['REMOTE_USER']; // 인증 메카니즘을 사용합니다.
$userfile = basename($_POST['user_submitted_filename']);
$homedir = "/home/$username";
$filepath = "$homedir/$userfile";
if (file_exists($filepath) && unlink($filepath)) {
$logstring = "Deleted $filepath\n";
} else {
$logstring = "Failed to delete $filepath\n";
}
$fp = fopen("/home/logging/filedelete.log", "a");
fwrite($fp, $logstring);
fclose($fp);
echo htmlentities($logstring, ENT_QUOTES);
?>
Example #4 좀더 안전한 파일명 체크
<?php
$username = $_SERVER['REMOTE_USER']; // 인증 메카니즘을 사용합니다.
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
$filepath = "$homedir/$userfile";
if (!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $userfile)) {
die("Bad username/filename");
}
//etc...
?>
운영체제에 따라, 장치엔트리(/dev/ or COM1) 및 설정 파일들(/etc/ files and the .ini files), 잘알려질 저장 장소들(/home/, My Documents) 등등. 신경써야할 파일은 많아 집니다. 이런 이유로, 명시적으로 허용하는것 이외에 모든것을 금지하는 정책을 만드는게 더 쉽습니다.