PHP 보안의 약방의 감초 open_basedir
로빈아빠
본문
오늘은 PHP보안에 있어 중요하지만 또한 많은 사람이 모르고 있는 open_basedir이라는 옵션에 대해 이야기 해보도록 하자.
우선 내가 운영하는 서버의 경우 php.ini에 다음과 같은 무식한 옵션이 있었다.
이 얼마나 무식한가? 하지만 저것도 다 막은것이 아니다.
심지어 fopen같은 경우에는 사용하는 웹어플리케이션이 너무 많아 막을수가 없었다.
뭐랄까, 도둑이 들까봐, 창문 잠그고 굴둑도 막아버렸는데, 대문을 활짝 열어놓은 기분이랄까?
PHP에는 safe_mode라는 훌륭한 보안 모드가 있다. 하지만 이것을 사용하면 대부분의 웹어플리케이션이 비정상 작동을 하게 된다.
제로보드가 잠식하고 있는 우리나라의 웹호스팅 업계에서는 엄두도 낼수 없는 옵션이다.
다음과 같은 코드를 작성하여 실행해 보자.
어떤 결과가 나오는가? 아주 멋지게 우리가 필요로 하는 정보를 내뿜어 준다.
disable_function에 fopen을 추가해 보자. 수많은 난관을 만나게 된다. 당장에 테터툴즈가 설치가 안되더라;
php.ini에 있는 open_basedir에 현재 서비스 하고 있는 페이지의 Document Root를 넣어보자. (예 : /var/www)
그리고 다시 시도해보자. 되는가? 잔인한 Fatal Error를 만나게 될것이다.
하지만 마찬가지로, PHP에서 세션을 저장하거나 업로드 파일을 올릴때 사용하는 /tmp등도 접근할수 없게 된다.
어떻게 해야 할까? 옵션을 지정할때 :를 구분자로 주어 여러개 지정할수 있다.
와 같이 설정해보자. 어떤가? 잘 되는것을 확인할수 있다.
안된다면 upload_tmp_dir 와 session.save_path 가 /tmp로 지정되어있는지부터 확인하여야 할것이다.
만약에 웹호스팅을 하고 있다면? open_basedir옵션이 없으면 더더욱 골치가 아파지게 된다.
누구든지 다른 사람의 계정의 파일을 열어볼수 있다면? "항상 적은 내부에 있다"
apache의 설정파일에서 VirtualHost부분을 찾아서 다음과 같이 php_admin_value로 값을 설정하자.
이런식으로 모든 가상호스트에 대해 설정을 하면 동일한 결과를 볼수 있다.
하지만 이것은 PHP의 함수들에 대한 제제일뿐이다. system("cat /etc/passwd")같은 명령은 어찌할수가 없다.
system명령을 disable_function에 추가해 버릴까? 이부분에 대해서는 다음에 좀더 이야기 해보도록 하자.
PS : upload_tmp_dir, session.save_path 을 /tmp가 아닌, 다른곳으로 변경한다면, 웹인젝션을 시도하는 나쁜놈들이 좀더 헷갈리게 할수 있겠죠?
우선 내가 운영하는 서버의 경우 php.ini에 다음과 같은 무식한 옵션이 있었다.
disable_functions = php_uname, putenv, getmyuid, getmypid, passthru, leak, listen, diskfreespace,
tmpfile, link, ignore_user_abord, shell_exec, popen, dl, set_time_limit, exec, system,
highlight_file, source, show_source, fpaththru, virtual, posix_ctermid, posix_getcwd,
posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups,
posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix_getppid, posix_getpwnam,
posix_getpwuid, posix_getrlimit, posix_getsid, posix_getuid, posix_isatty, posix_kill, posix_mkfifo,
posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsid, posix_setuid, posix_times,
posix_ttyname, posix_uname
이 얼마나 무식한가? 하지만 저것도 다 막은것이 아니다.
심지어 fopen같은 경우에는 사용하는 웹어플리케이션이 너무 많아 막을수가 없었다.
뭐랄까, 도둑이 들까봐, 창문 잠그고 굴둑도 막아버렸는데, 대문을 활짝 열어놓은 기분이랄까?
PHP에는 safe_mode라는 훌륭한 보안 모드가 있다. 하지만 이것을 사용하면 대부분의 웹어플리케이션이 비정상 작동을 하게 된다.
제로보드가 잠식하고 있는 우리나라의 웹호스팅 업계에서는 엄두도 낼수 없는 옵션이다.
다음과 같은 코드를 작성하여 실행해 보자.
<?
$fp=fopen("/etc/passwd", "r");
while(!feof($fp)) {
print(fread($fp, 4096));
flush();
}
?>
어떤 결과가 나오는가? 아주 멋지게 우리가 필요로 하는 정보를 내뿜어 준다.
disable_function에 fopen을 추가해 보자. 수많은 난관을 만나게 된다. 당장에 테터툴즈가 설치가 안되더라;
php.ini에 있는 open_basedir에 현재 서비스 하고 있는 페이지의 Document Root를 넣어보자. (예 : /var/www)
그리고 다시 시도해보자. 되는가? 잔인한 Fatal Error를 만나게 될것이다.
하지만 마찬가지로, PHP에서 세션을 저장하거나 업로드 파일을 올릴때 사용하는 /tmp등도 접근할수 없게 된다.
어떻게 해야 할까? 옵션을 지정할때 :를 구분자로 주어 여러개 지정할수 있다.
open_basedir /var/www:/tmp
와 같이 설정해보자. 어떤가? 잘 되는것을 확인할수 있다.
안된다면 upload_tmp_dir 와 session.save_path 가 /tmp로 지정되어있는지부터 확인하여야 할것이다.
만약에 웹호스팅을 하고 있다면? open_basedir옵션이 없으면 더더욱 골치가 아파지게 된다.
누구든지 다른 사람의 계정의 파일을 열어볼수 있다면? "항상 적은 내부에 있다"
apache의 설정파일에서 VirtualHost부분을 찾아서 다음과 같이 php_admin_value로 값을 설정하자.
<VirtualHost *>
DocumentRoot /home/USER
ServerName USER.domain
<IfModule mod_php5.c>
php_admin_value open_basedir /home/USER:/tmp
</IfModule>
</VirtualHost>
이런식으로 모든 가상호스트에 대해 설정을 하면 동일한 결과를 볼수 있다.
하지만 이것은 PHP의 함수들에 대한 제제일뿐이다. system("cat /etc/passwd")같은 명령은 어찌할수가 없다.
system명령을 disable_function에 추가해 버릴까? 이부분에 대해서는 다음에 좀더 이야기 해보도록 하자.
PS : upload_tmp_dir, session.save_path 을 /tmp가 아닌, 다른곳으로 변경한다면, 웹인젝션을 시도하는 나쁜놈들이 좀더 헷갈리게 할수 있겠죠?
댓글목록
등록된 댓글이 없습니다.