PHP 옵션 'cgi.fix_pathinfo'는 Nginx + PHP-FPM에서 실제로 위험합니까?


51

가 발생했습니다 많은 이야기 받는 보안 문제 상대에 대한 Nginx에 (일반적으로 PHP-FPM, 빠른 CGI)와 함께 사용 PHP 옵션을 선택합니다. cgi.fix_pathinfo

결과적으로 기본 nginx 구성 파일은 다음과 같이 말합니다.

# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

그러나 "공식적인"Nginx 위키 는 위의 PHP 옵션을 비활성화하지 않고도 PATH_INFO를 올바르게 처리 할 수 ​​있다고 말합니다 . 그래서 무엇?

질문

  • 무엇을하는지 명확하게 설명 할 수 있습니까 cgi.fix_pathinfo? ( 공식 문서는 다음과 같이 말합니다 . "PATH_INFO에 대한 자세한 내용은 CGI 사양을 참조하십시오")
  • PHP는 이러한 변수 PATH_INFOSCRIPT_FILENAME변수로 실제로 무엇을 합니까?
  • 왜 그리고 어떻게 Nginx에 위험 할 수 있습니까? ( 자세한 예)
  • 이 프로그램의 최신 버전에 여전히 문제가 있습니까?
  • Apache는 취약합니까?

각 단계에서 문제를 이해하려고합니다. 예를 들어, php-fpm Unix 소켓을 사용하면 이 문제를 피할 수 있는 이유를 이해하지 못합니다 .


1
: 당신은 PATH_INFO와 PATH_TRANSLATED의 차이점을 이해하여 자신의 질문에 대답 할 수 blogs.msdn.com/b/david.wang/archive/2005/08/04/...
조반니 Tirloni

답변:


79

TL; DR-수정 (필요하지 않을 수도 있음)은 매우 간단 하며이 답변의 끝 부분에 있습니다.

특정 질문에 답하려고 노력할 것입니다. 그러나 PATH_INFO가 무엇인지에 대한 당신의 오해는 질문 자체를 조금 잘못합니다.

  • 첫 번째 질문은 "이 경로 정보 비즈니스 란 무엇입니까?"

  • 당신의 다음 질문은 했어야 : "어떻게 PHP는 무엇을 결정 하는가 PATH_INFO하고 SCRIPT_FILENAME있다?"

    • PHP의 이전 버전은 기술적으로도 지원하지 않았다 순진했고 PATH_INFO있어야했다 그래서 무엇 PATH_INFO에 munged 한 SCRIPT_FILENAME예, 많은 경우에 고장,있다. 테스트 할만큼 오래된 버전의 PHP가 없지만 SCRIPT_FILENAME위의 예제에서 "/path/to/script.php/THIS/IS/PATH/INFO"라는 전체 내용을 볼 수 있습니다. 평소와 같이 docroot).
    • 활성화 cgi.fix_pathinfo으로, PHP는 올바르게 "/ 본 / IS / PATH / INFO"위의 예를 찾아로두고 PATH_INFO하고 SCRIPT_FILENAME(물론 docroot에 접두사) 요청 된 스크립트를 가리키는 단지 부분을 가져옵니다.
    • 참고 : PHP가 실제로 지원하기 시작했을 때 PATH_INFO, 새로운 기능에 대한 구성 설정을 추가해야 이전 동작에 의존하는 스크립트를 실행하는 사람들이 새로운 PHP 버전을 실행할 수있었습니다. 그렇기 때문에 구성 스위치도 있습니다. 처음부터 내장되어 있어야합니다 ( "위험한"동작으로).
  • 그러나 PHP는 스크립트의 어느 부분과 경로 정보를 어떻게 알 수 있습니까? URI가 다음과 같은 경우 :

    http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo

    • 일부 환경에서는 복잡한 질문 일 수 있습니다. PHP에서 발생하는 일은 서버의 docroot 아래에 해당하지 않는 URI 경로의 첫 부분을 찾는 것입니다. 이 예제에서는 서버에 "/docroot/path/to/script.php/THIS"가 없지만 "/docroot/path/to/script.php"가 있으므로 SCRIPT_FILENAME결정되어 PATH_INFO나머지를 얻습니다.
    • 이제 Nginx 문서와 Hrvoje Špoljar의 답변 (이러한 명확한 예에 대해 까다로울 수 없음)에 자세히 설명 된 위험의 좋은 예가 더 명확 해집니다 .Hrvoje의 예 ( " http : // example. com / foo.jpg / nonexistent.php "), PHP는 docroot"/foo.jpg "에서 파일을 볼 수 있지만"/foo.jpg/nonexistent.php "라는 파일은 보이지 않으므로"/foo.jpg "를 SCRIPT_FILENAME얻습니다. (docroot 접두사가 붙음) PATH_INFO"/nonexistent.php"를 얻습니다.
  • 위험 할 수있는 이유와 방법이 명확 해졌습니다.

    • 웹 서버는 실제로 잘못이 아닙니다. URI로 PHP를 프록시하는 것입니다. "foo.jpg"에 실제로 PHP 내용이 포함되어 있다는 사실을 순진하게 찾아서 실행합니다. 이것은 Nginx 자체에 국한 되지 않습니다 .
  • 진짜 문제는 신뢰할 수없는 콘텐츠는 살균하지 않고 어딘가에 업로드 할 당신이 그것을 할 수있는 PHP가 행복하게 실행 동일한 위치에 다른 임의의 요청을 허용 할 수 있다는 것입니다.
  • Nginx와 Apache는이 속임수를 사용하여 요청을 방지하도록 빌드하거나 구성 할 수 있으며 user2372674의 답변을 포함하여이를 수행하는 방법에 대한 많은 예제가 있습니다 . 이 블로그 기사 는 문제를 훌륭하게 설명하지만 올바른 해결책이 없습니다.

  • 그러나 가장 좋은 해결책은 ".php"로 끝나지 않는 한 파일을 실행하지 않도록 PHP-FPM이 올바르게 구성되어 있는지 확인하는 것입니다. 최신 버전의 PHP-FPM (~ 5.3.9 +?)이 기본값으로 설정되어 있으므로이 위험은 더 이상 문제가되지 않습니다.

해결책

최신 버전의 PHP-FPM (~ 5.3.9 +?)이있는 경우 아래의 안전한 동작이 이미 기본값이므로 아무 것도 수행하지 않아도됩니다.

그렇지 않으면 php-fpm의 www.conf파일을 찾으 /etc/php-fpm.d/www.conf십시오 (시스템에 따라 다름). 이것을 가지고 있는지 확인하십시오 :

security.limit_extensions = .php

다시 말하지만, 요즘 많은 곳에서 기본값입니다.

이로 인해 공격자가 ".php"파일을 WordPress 업로드 폴더에 업로드하고 동일한 기술을 사용하여 파일을 실행하는 것을 막을 수는 없습니다. 여전히 애플리케이션에 대한 보안이 우수해야합니다.


5
좋은 대답입니다! 명확히하기 위해 : PHP가 무엇을 결정 SCRIPT_FILENAME하면 왜 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;nginxconf에 줄이 있습니까? SCRIPT_FILENAME그 자체 의 가치를 발견하려는 PHP의 노력을 무시합니까 ?
Totor

의 가치를 얻는 기능이 security.limit_extensions있습니까? 나는 노력 phpinfo(), ini_get(security.limit_extensions)그리고 ini_get_all()성공하지 못했다.
elbowlobstercowstand

최신 버전의 PHP-FPM (~ 5.3.9 +?)에 기본값이 있다면 php7.1에 왜 필요한가요? 아니면 기사가 잘못 되었습니까?
예브게니 아파 나시 예프

14

본질적으로 이것이 없으면 'foo.jpg'와 같은 PHP 코드를 가진 파일을 웹 서버에 업로드 할 수 있습니다. 그런 다음 http : //domain.tld/foo.jpg/nonexistent.php 와 같이 요청하면 웹 서버 스택이 실수로 oh라고 말합니다. 이것은 PHP입니다. 이것을 처리해야합니다 .foo.jpg / nonexistent.php를 찾지 못하면 foo.jpg로 돌아가서 foo.jpg를 PHP 코드로 처리합니다. 시스템을 매우 쉽게 침입 할 수 있으므로 위험합니다. 예를 들어 이미지 업로드를 허용하는 모든 웹 응용 프로그램은 백도어를 업로드하는 도구가됩니다.

유닉스 소켓에서 php-fpm을 사용하는 것을 피하기 위해; IMO는 문제를 해결하지 못합니다.


내가 제공 한 링크에서 읽을 수있는 내용 만 반복하십시오. 실제 메커니즘은 설명하지 않습니다. 당신의 대답은 부가 가치 IMHO가 필요합니다.
Totor

6
사실 일 수도 있지만 제목에 해당 질문에 대한 답변이 있습니다. 당신이 그것을 명시 적으로 원한다면; 예, 위험합니다. 매우 위험한.
Hrvoje Špoljar

1 / 내 대답은 제목에 국한되지 않으며 본문이 있습니다. 2 / user109322 는 당신이 틀렸다는 것을 입증했습니다 : 기본 conf 가 안전 하기 때문에 ( 값 이 확장 된 파일 만 실행 하기 때문에) 사용 된 값 cgi.fix_pathinfo이 위험 하지 않습니다 . php-fpm.php
Totor

2

에서 Nginx에 위키 보안 조치로

if (!-f $document_root$fastcgi_script_name) {
    return 404;
}

위치 블록에 포함됩니다. 다른 튜토리얼에서

try_files $uri =404;

Nginx 위키에 따라 문제가 발생할 수 있지만 동일하게 수행되어야합니다. 이러한 옵션을 사용하면 cgi.fix_pathinfo=1더 이상 문제가되지 않습니다. 자세한 정보는 여기를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.