>백엔드 개발 >PHP 튜토리얼 >PHP 파일 시스템 보안 및 예방 조치

PHP 파일 시스템 보안 및 예방 조치

伊谢尔伦
伊谢尔伦원래의
2016-11-22 10:48:251327검색

PHP는 대부분의 서버 시스템에서 파일 및 디렉토리 권한과 관련된 보안 메커니즘을 준수합니다. 이를 통해 관리자는 파일 시스템 내에서 읽을 수 있는 파일을 제어할 수 있습니다. 전역적으로 읽을 수 있는 파일에 특별한 주의를 기울여야 하며 모든 승인된 사용자가 이러한 파일을 안전하게 읽을 수 있도록 보장해야 합니다.

PHP는 사용자 수준에서 파일 시스템에 액세스하도록 설계되었으므로 /etc/passwd와 같은 시스템 파일 읽기, 네트워크 연결 변경, 대량 전송 등의 PHP 코드 작성이 전적으로 가능합니다. 인쇄 작업 등 따라서 PHP 코드가 적절한 파일을 읽고 쓰고 있는지 확인해야 합니다.

아래 코드를 보세요. 사용자가 자신의 홈 디렉터리에 있는 파일을 삭제하려고 합니다. 이 시나리오에서는 파일 시스템이 웹 인터페이스를 통해 관리되므로 Apache 사용자에게 사용자 디렉터리의 파일을 삭제할 수 있는 권한이 있다고 가정합니다.

예제 #1 변수에 대한 보안 검사를 수행하지 않으면...

<?php
    // 从用户目录中删除指定的文件
    $username = $_POST[&#39;user_submitted_name&#39;];
    $userfile = $_POST[&#39;user_submitted_filename&#39;];
    $homedir = "/home/$username";
    unlink ("$homedir/$userfile");
    echo "The file has been deleted!";
?>

사용자 이름 및 파일 이름 변수는 사용자 양식을 통해 제출할 수 있으므로 다른 사람의 변수를 제출할 수 있습니다. 사용자 이름과 파일 이름, 애초에 삭제하면 안 되는 파일도 삭제할 수 있습니다. 이 경우 다른 인증 방법을 고려해야 합니다. 제출된 변수가 "../etc/" 및 "passwd"인 경우 어떤 일이 발생할지 생각해 보세요. 위의 코드는 다음과 같습니다.

예제 #2... 파일 시스템 공격

<?php
    // 删除硬盘中任何 PHP 有访问权限的文件。如果 PHP 有 root 权限:
    $username = $_POST[&#39;user_submitted_name&#39;]; // "../etc"
    $userfile = $_POST[&#39;user_submitted_filename&#39;]; // "passwd"
    $homedir = "/home/$username"; // "/home/../etc"
    unlink("$homedir/$userfile"); // "/home/../etc/passwd"
    echo "The file has been deleted!";
?>

이런 문제를 방지하려면 두 가지 중요한 조치가 필요합니다.

PHP 웹 사용자에게 매우 제한된 권한만 부여합니다.

제출된 변수를 모두 확인하세요.

개선된 스크립트는 다음과 같습니다.

예제 #3 더 안전한 파일 이름 확인

<?php
    // 删除硬盘中 PHP 有权访问的文件
    $username = $_SERVER[&#39;REMOTE_USER&#39;]; // 使用认证机制
    $userfile = basename($_POST[&#39;user_submitted_filename&#39;]);
    $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);
?>

그러나 여기에는 여전히 결함이 있습니다. 인증 시스템에서 사용자가 자신의 로그인 사용자 이름을 만들 수 있도록 허용하고 사용자가 "../etc/"를 사용자 이름으로 사용하도록 선택하면 시스템이 다시 실패합니다. 따라서 검사 강화가 필요합니다:

예시#4 더욱 안전한 파일명 검사

<?php
    $username = $_SERVER[&#39;REMOTE_USER&#39;]; // 使用认证机制
    $userfile = $_POST[&#39;user_submitted_filename&#39;];
    $homedir = "/home/$username";
    $filepath = "$homedir/$userfile";
    if (!ctype_alnum($username) || !preg_match(&#39;/^(?:[a-z0-9_-]|\.(?!\.))+$/iD&#39;, $userfile)) {
        die("Bad username/filename");
    }
    //后略……
?>

운영 체제에 따라 관련 파일을 포함하여 주의가 필요한 다양한 파일이 있습니다. 시스템 장치(/dev/ 또는 COM1), 구성 파일(/ect/ 파일 및 .ini 파일), 일반적으로 사용되는 저장 영역(/home/ 또는 내 문서) 등에 이러한 이유로 모든 권한을 비활성화하고 명시적으로 허용된 권한만 활성화하는 정책을 설정하는 것이 더 쉬운 경우가 많습니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.