PHP를 서버측 소프트웨어(Apache 등)에 내장하고 모듈로 설치하고 싶지 않은 경우 CGI 모드로 설치하도록 선택할 수 있습니다. 또는 다양한 CGI 래퍼와 함께 PHP를 사용하여 코드에 대한 보안 chroot 및 setuid 환경을 만듭니다. 이 설치 방법은 일반적으로 웹 서버의 cgi-bin 디렉터리에 PHP 실행 파일을 설치합니다. PHP는 독립형 인터프리터로 사용될 수 있지만 다음 유형의 공격에 저항하도록 설계되었습니다.
시스템 파일 액세스: http://my.host/cgi-bin/php?/etc/passwd URL 요청에서 물음표(?) 뒤의 정보는 명명된 줄의 매개변수로 CGI 인터페이스에 전달됩니다. 다른 인터프리터는 명령줄의 첫 번째 인수로 지정된 파일을 열고 실행합니다. 그러나 CGI 모드로 설치된 PHP 인터프리터가 호출되면 이러한 매개변수 해석을 거부합니다.
서버의 모든 디렉터리에 액세스합니다: http://my.host/cgi-bin/php/secret/doc.html 위의 경우 PHP 인터프리터가 있는 디렉터리 뒤에 있는 URL 정보는 다음과 같습니다. /secret/ doc.html은 정기적으로 CGI 프로그램에 전달되어 해석됩니다. 일반적으로 일부 웹 서버는 이를 http://my.host/secret/script.php와 같은 페이지로 리디렉션합니다. 이 경우 일부 서버는 http://my.host/cgi-bin/php/secret/script.php 페이지로의 리디렉션을 생성하기 전에 /secret 디렉토리에 액세스할 수 있는 사용자 권한을 확인합니다. 안타깝게도 많은 서버에서는 /secret/script.php에 대한 사용자의 액세스 권한을 확인하지 않고 /cgi-bin/php의 권한만 확인하므로 /cgi-bin/php에 액세스할 수 있는 모든 사용자가 웹 디렉토리에 액세스할 수 있습니다. 어떤 파일의. PHP에서 컴파일 타임 구성 옵션 --enable-force-cgi-redirect와 런타임 구성 지침 doc_root 및 user_dir은 이러한 공격을 방지하기 위해 서버의 파일 및 디렉터리에 제한을 추가할 수 있습니다. 각 옵션의 설정에 대해서는 아래에서 자세히 설명하겠습니다.
사례 1: 공개 파일만 실행
웹 서버의 모든 콘텐츠가 비밀번호나 IP 주소로 제한되어 있는 경우에는 이 옵션을 설정할 필요가 없습니다. 웹 서버가 리디렉션을 지원하지 않거나 웹 서버가 PHP와 통신하여 액세스 요청을 더욱 안전하게 만들 수 없는 경우 구성 스크립트에서 --enable-force-cgi-redirect 옵션을 지정할 수 있습니다. 또한, PHP 프로그램이 http://my.host/cgi-bin/php/dir/script.php에 직접 접근하거나 리디렉션을 통해 접근하는 등 다른 호출 방식에 의존하지 않는지 확인하는 것도 필요하다. http://my .host/dir/script.php로.
Apache에서는 AddHandler 및 Action 문을 사용하여 리디렉션을 설정할 수 있습니다.
사례 2: --enable-force-cgi-redirect 옵션 사용
이 컴파일 옵션은 누구든지 http://my.host/cgi-bin/php/secretdir A에 액세스하는 것을 방지합니다. /script.php와 같은 URL은 PHP를 직접 호출합니다. 이 모드의 PHP는 웹 서버의 리디렉션 규칙을 통과한 URL만 구문 분석합니다.
일반적으로 Apache의 리디렉션 설정은 다음 명령으로 완료할 수 있습니다.
Action php-script /cgi-bin/php AddHandler php-script .php
이 옵션은 Apache에서만 테스트되었으며 리디렉션 작업에서 Apache가 설정한 내용에 따라 달라집니다. 표준 CGI 환경 변수 REDIRECT_STATUS. 웹 서버가 요청이 직접인지 리디렉션인지 확인하는 방법을 지원하지 않는 경우 이 옵션을 사용할 수 없으며 다른 방법을 사용해야 합니다.
시나리오 3: doc_root 또는 user_dir 설정
웹 서버의 기본 문서 디렉터리에 스크립트 및 실행 프로그램과 같은 동적 콘텐츠를 포함하는 것은 때때로 안전하지 않은 관행으로 간주됩니다. 구성 오류로 인해 스크립트가 실행되지 않고 일반 HTML 문서로 표시되는 경우 지적 재산이나 비밀번호 정보가 유출될 수 있습니다. 따라서 많은 시스템 관리자는 PHP CGI를 통해서만 액세스할 수 있는 디렉터리를 특별히 설정하여 해당 디렉터리의 내용을 구문 분석만 하고 그대로 표시하지는 않습니다.
위에서 언급한 리디렉션 여부 결정이 불가능한 상황의 경우 기본 문서 디렉토리 외부에 스크립트 전용 doc_root 디렉토리를 생성해야 합니다.
구성 파일의 doc_root를 통해 또는 환경 변수 PHP_DOCUMENT_ROOT를 설정하여 PHP 스크립트 홈 디렉터리를 정의할 수 있습니다. 이 옵션이 설정되면 PHP는 doc_root 디렉토리에 있는 파일만 해석하고 디렉토리 외부의 스크립트는 PHP 인터프리터에 의해 실행되지 않도록 합니다(아래 언급된 user_dir 제외).
사용 가능한 또 다른 옵션은 user_dir입니다. user_dir이 설정되지 않은 경우 doc_root는 파일이 열리는 위치를 제어하는 유일한 옵션입니다. http://my.host/~user/doc.php와 같은 URL에 접속하면 사용자 홈 디렉터리의 파일은 열리지 않고, doc_root 디렉터리의 ~user/doc.php만 실행됩니다. 하위 디렉터리는 시작 부분이 [ ~]로 시작됩니다.
public_php와 같이 user_dir이 설정된 경우 http://my.host/~user/doc.php와 같은 요청은 사용자 홈 디렉터리의 public_php 하위 디렉터리에 있는 doc.php 파일을 실행합니다. 사용자 홈 디렉터리의 절대 경로를 /home/user라고 가정하면, 실행되는 파일은 /home/user/public_php/doc.php가 됩니다.
user_dir 的设置与 doc_root 无关,所以可以分别控制 PHP 脚本的主目录和用户目录。
情形四:PHP 解释器放在 web 目录以外
一个非常安全的做法就是把 PHP 解释器放在 web 目录外的地方,比如说 /usr/local/bin。这样做唯一不便的地方就是必须在每一个包含 PHP 代码的文件的第一行加入如下语句:
#!/usr/local/bin/php
还要将这些文件的属性改成可执行。也就是说,要像处理用 Perl 或 sh 或其它任何脚本语言写的 CGI 脚本一样,使用以 #! 开头的 shell-escape 机制来启动它们。
在这种情况下,要使 PHP 能正确处理 PATH_INFO 和 PATH_TRANSLATED 等变量的话,在编译 PHP 解释器时必须加入 --enable-discard-path 参数。