본문 바로가기

Info

[PHP] 소유권에 의한 보안

글쓴이:해원  [응답]php fopen() 보안에 대한 내용입니다. 서버관리자분들 읽어주세요 조회수:2780


해원



이 문제를 제기했던 사람입니다.
매우 중요한 문제로 오래전 부터 고민해왔는데
아직도 해결책이 없군요.

몇가지 정리를 해보았습니다.

(1). telnet, ftp 등의 로긴 후 보안 문제

   이 문제는 한 사용자가 서버에 로긴을 하여 다른 사용자의
   php script 를 읽는 것을 방지하는 방법입니다. 이 문제는
   완벽한 해결책이 있습니다.

   solaris 의 경우는 setfacl 을 사용한다고 하지만
   순전히 permission 만 잘 설정해도 가능합니다.
   Linux 에서도 잘 됩니다. 아래에 그 방법을 소개합니다.

   apache 의 user, group 이 각각 nobody, nobody 라고
   하고 web hosting directory 는 /home/httpd 밑에 있다고
   가정합시다.  사용자 계정이 aaa, bbb, 등이라고 하면
   다음과 같이 permission 을 설정하면 됩니다.

   rwx--x--x    nobody nobody    /home/httpd
   rwx--x---    aaa    nobody    /home/httpd/aaa
   rwx--x---    bbb    nobody    /home/httpd/bbb

   예를 들어 계정 aaa 의 php script sample.php 의 permission이
   다음과 같다고 합시다.

   rw-rw-r--    aaa    aaa     /home/httpd/aaa/sample.php

   이렇게 되면 sample.php 가 664 라 해도 nobody group 에 속한
   ID (즉 apache) 만 이 화일을 볼 수 있습니다. 다른 ID, 예를
   들어 bbb, 에게는 /home/httpd/aaa 가 잠겨있기 때문에
   sample.php 를 읽을 수 없습니다.


(2). fopen() 방지 문제

   한 계정에서 php 스크립트 안에 fopen()과 같은 종류의
   명령을 넣어 다른 계정의 php 문서를 읽는 문제입니다.

   위의 (1) 의 문제와는 별도 문제입니다. ((1)의 조치를
   취했다해도 이 문제는 전혀 해결된 것이 아닙니다.)

   (a) php 의 safe_mode 를 사용하는 방법

    php.ini 에서 safe_mode 를 On 하면 실행중인 php
    스크립트의 소유자와 그 스크립트내에서 fopen()을
   하고자 하는 화일의 소유자 같은지 검사하고 같은 경우만
   허용됩니다.

   safe_mode 가 On 된 상태에서 php 스크립트에서 화일을
   만들 경우 만들어지는 모든 화일은 nobody 의 소유가 됩니다.
   디렉토리도 마찬가지임.

   너무나 완벽(?)하게 틀어 막아 문제가 있습니다.
   다른 분이 지적하셨듯이 이 경우 Upload / Download 에
   문제가 있습니다.

   Upload 하는 경우 Upload directory 가
   그 php 스크립트의 소유자(aaa)가 소유해야 하고
   apache의 User 인 nobody 도 쓸수 있게 되어 있어야 합니다.
   실제로 만들어지는 화일은 nobody의 소유가 됩니다.
  
   그런데 이 화일의 소유자가 nobody 임으로 계정 aaa 에
   속한 php 스크립트로는 fopen() 으로 이 화일을 읽지
   못하는 일이 발생합니다. 따라서 이 화일을 download
   되게 하려면 html 문서가 있는 장소에 넣어 직접 download
   가 가능하게 해야 합니다.

   운영상의 묘를 찾는 방법은 있습니다.
   webhosting 하는 서버의 경우 게시판등은 시스템에서 제공하고
   (즉 게시판 스크립트들은 nobody 의 소유로 하는 겁니다.)
   각 계정에서는 upload 를 금지하는 방법입니다.

   필자로서는 이 방법이 가장 무난하다고 봅니다. 보안은
   철저해야 하기 때문에..

   결론은 아직 해결책이 완전하지 않다는 것입니다.
   그러나 php 를 더 좋게 보완하는 방법도 떠오르지 않는
   상황입니다.
  

   (b) suexec, cgi 를 사용하는 방법

   virtual host를 설정하되 SUEXEC 를 사용하는 방법입니다.
   그리고 PHP 스크립트를 CGI 모드로 작동되게 합니다.
   그리고 이 스크립트들을 자신만이 읽을 수 있게
   permission을 700 로 합니다.  이제는 CGI를 샐행할 때 아파치는
   권한을 해당 UID로 switching 하기 다른 계정의 PHP 문서는
   읽을 수 없습니다. (700 이므로)

   이 방법은 완벽하나 다음과 같은 단점이 있습니다.

   단점으로는 MODULE 방식이 아니고 CGI 방식으로 속도가
   느려진다는 것과 SUEXEC 설정을 잘 해야 한다는 것입니다.
   또한 대량의 web hosting (VirtualDocumentRoot을 사용하는
   경우)은 어렵다는 것입니다.
  

   (c) disable_functions 을 사용하는 방법

   이 방법으로 여러 함수들을 금지시킬 수 있는데
   fopen() 외에도 위험한 것들이 아주 많이 있습니다.
   예를 들어 popen(), readfile() , ....
   위험 한 것은 다 금지시켜야 하겠습니다.
   이 경우 우리가 원하는 많은 기능을 포기해야하는 문제가
   생깁니다.