Info
[PHP] 소유권에 의한 보안
카카루카
2004. 1. 12. 19:35
글쓴이:해원 [응답]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() , ....
위험 한 것은 다 금지시켜야 하겠습니다.
이 경우 우리가 원하는 많은 기능을 포기해야하는 문제가
생깁니다.
해원
이 문제를 제기했던 사람입니다.
매우 중요한 문제로 오래전 부터 고민해왔는데
아직도 해결책이 없군요.
몇가지 정리를 해보았습니다.
(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() , ....
위험 한 것은 다 금지시켜야 하겠습니다.
이 경우 우리가 원하는 많은 기능을 포기해야하는 문제가
생깁니다.