어떤 $ _SERVER 변수가 안전합니까?


97

사용자가 제어 할 수있는 모든 변수, 공격자도 제어 할 수 있으므로 공격의 원인이됩니다. 이를 "오염 된"변수라고하며 안전하지 않습니다.

를 사용 $_SERVER하면 많은 변수를 제어 할 수 있습니다. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGE많은 다른 사람들이 클라이언트에서 보낸 HTTP 요청 헤더의 일부입니다.

누구든지 "안전 목록"이나 오염되지 않은 $_SERVER변수 목록을 알고 있습니까?


8
"안전"을 정의하는 방법에 따라 다릅니다. 값은 모두 안전 하며 용도에 따라 다릅니다.
deceze

6
이 맥락에서 Rook은 "사용자가 스푸핑 할 수없는 서버 변수"를 말합니다 REMOTE_ADDR.
vcsjones 2011-06-24

6
로 시작하는 모든 HTTP_것은 요청 헤더이며 그 사이의 브라우저 또는 프록시에서 설정할 수 있습니다. 나는 그것들을 다른 사용자 입력으로 간주 할 것입니다.
datasage

3
@ bob-the-destroyer REMOTE_ADDR은 아파치의 TCP 소켓에서 직접 가져옵니다.이 값 3 방향 핸드 셰이크 때문에 인터넷을 통해 스푸핑 될 수 없습니다 .
rook

2
@Rook : 좋은 지적입니다. 나는 "스푸핑"에 대한 언급과 함께의 실제 가치를 속이는 것보다 ip 스푸핑 자체의 오래된 행위에 더 의존하고 있었던 것 같습니다 REMOTE_ADDR. 그리고 그것은이 질문의 범위를 벗어납니다. 이 값이 어떻게 설정되는지에 대한 통찰력을 얻을 수있어서 좋습니다. 감사합니다.
bob-the-destroyer

답변:


147

"안전한"또는 "안전하지 않은"값과 같은 것은 없습니다. 서버가 제어하는 ​​값과 사용자가 제어하는 ​​값만 있으며 값의 출처와 특정 목적에 대해 신뢰할 수 있는지 여부를 알아야합니다. $_SERVER['HTTP_FOOBAR']예를 들어 데이터베이스에 저장하는 것은 전적으로 안전하지만, 저는 그렇지 않습니다 eval.

따라서 이러한 값을 세 가지 범주로 나눕니다.

서버 제어

이러한 변수는 서버 환경에 의해 설정되며 전적으로 서버 구성에 따라 다릅니다.

  • 'GATEWAY_INTERFACE'
  • 'SERVER_ADDR'
  • 'SERVER_SOFTWARE'
  • 'DOCUMENT_ROOT'
  • 'SERVER_ADMIN'
  • 'SERVER_SIGNATURE'

부분적으로 서버 제어

이러한 변수는 클라이언트가 보낸 특정 요청에 따라 다르지만 유효하지 않은 값은 모두 웹 서버에서 거부해야하고 스크립트 호출을 시작하지 않아야하기 때문에 제한된 수의 유효한 값만 사용할 수 있습니다. 따라서 신뢰할 수있는 것으로 간주 될 수 있습니다 .

  • 'HTTPS'
  • 'REQUEST_TIME'
  • 'REMOTE_ADDR' *
  • 'REMOTE_HOST' *
  • 'REMOTE_PORT' *
  • 'SERVER_PROTOCOL'
  • 'HTTP_HOST'
  • 'SERVER_NAME'
  • 'SCRIPT_FILENAME'
  • 'SERVER_PORT'
  • 'SCRIPT_NAME'

* REMOTE_값은 TCP / IP 핸드 셰이크에 의해 확인 된 클라이언트의 유효한 주소임을 보장합니다. 응답이 전송 될 주소입니다. REMOTE_HOST하지만 역방향 DNS 조회에 의존하므로 서버에 대한 DNS 공격으로 스푸핑 될 수 있습니다 (이 경우 더 큰 문제가 발생합니다). 이 값은 프록시 일 수 있으며 이는 TCP / IP 프로토콜의 단순한 현실이며 사용자가 할 수있는 작업이 없습니다.

† 웹 서버 가 헤더에 관계없이 요청에 응답하는 경우에도HOST 안전하지 않은 것으로 간주되어야합니다. $ _SERVER [ "HTTP_HOST"]는 얼마나 안전합니까?를 참조하십시오 . . http://shiflett.org/blog/2006/mar/server-name-versus-http-host
도 참조 하십시오 .

https://bugs.php.net/bug.php?id=64457 , http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalport , http : //httpd.apache를 참조 하십시오 . org / docs / 2.4 / mod / core.html # comment_999

완전히 임의의 사용자 제어 값

이러한 값은 전혀 확인되지 않으며 서버 구성에 의존하지 않으며 클라이언트가 보내는 전적으로 임의의 정보입니다.

  • 'argv', 'argc'(CLI 호출에만 적용 가능하며 일반적으로 웹 서버에는 문제가되지 않음)
  • 'REQUEST_METHOD' §
  • 'QUERY_STRING'
  • 'HTTP_ACCEPT'
  • 'HTTP_ACCEPT_CHARSET'
  • 'HTTP_ACCEPT_ENCODING'
  • 'HTTP_ACCEPT_LANGUAGE'
  • 'HTTP_CONNECTION'
  • 'HTTP_REFERER'
  • 'HTTP_USER_AGENT'
  • 'AUTH_TYPE' ''
  • 'PHP_AUTH_DIGEST' ''
  • 'PHP_AUTH_USER' ''
  • 'PHP_AUTH_PW' ''
  • 'PATH_INFO'
  • 'ORIG_PATH_INFO'
  • 'REQUEST_URI' (오염 된 데이터를 포함 할 수 있음)
  • 'PHP_SELF' (오염 된 데이터를 포함 할 수 있음)
  • 'PATH_TRANSLATED'
  • 다른 'HTTP_'

§ 웹 서버가 특정 요청 방법 만 허용하는 한 신뢰할 수있는 것으로 간주 될 수 있습니다 .

'' 인증이 전적으로 웹 서버에서 처리되는 경우 신뢰할 수있는 것으로 간주 될 수 있습니다 .

수퍼 글로벌 $_SERVER에는 여러 환경 변수도 포함됩니다. 이것이 "안전"한지 여부는 정의 된 방법과 위치에 따라 다릅니다. 완전히 서버 제어에서 완전히 사용자 제어에 이르기까지 다양합니다.


3
@Rook 그러나 내가 말했듯이, 그것은 당신이 그것을 사용하는 방법에 절대적으로 달려 있습니다 . 단지 그 자체로 값이에 따라,도 안전도 안전하지 당신이 그들에게 무엇을 사용 . 악의적 인 사용자로부터 전송 된 데이터도 보안을 손상시킬 수있는 작업을 수행하지 않는 한 완벽하게 안전합니다.
deceze

2
@Rook : "안전"에 대한 당신의 생각은이 질문을 약간 임의적으로 보이게 만듭니다. 특히 그것은 완전히 모호한 확장이나 PHP의 사용자 정의 버전과 관련이 있기 때문입니다. "엉덩이에서 촬영하는"접근 방식을 사용해서는 안된다고 말하지만 실제로 이러한 값이 어떻게 설정되는지 알아 보려면 PHP 소스 코드에 대한 최소한의 지식이 필요한 것 같습니다. PHP 개발자에게 이메일을 보내는 것이 답을 찾는 더 좋은 방법이 아닐까요?
bob-the-destroyer

2
@Rook : 오해. 속임수가 암시했듯이 "어떤 목적을 위해 안전하다". 내가 암시했듯이, 귀하의 목적은 알 수 없으며 $_SERVER파일 제공 방법에 따라 문서화되지 않은 몇 가지 다른 값이 있습니다. 제 생각에는 문서화 된 자료가 진정한 출처를 명확히 밝히지 않습니다. 그렇지 않으면 나는 당신이이 질문을하지 않을 것이라고 믿습니다. 사용할 수있는 목록이있어 다행입니다. 하지만 버그 보고서를 제출하거나 (버그 사이트가 수정 된 경우), 문서 관리자에게 이메일을 보내거나, 문서를 직접 업데이트하는 것이 좋습니다 (링크에 대한 권한이있는 경우). 이 정보를 아는 것이 커뮤니티에 도움이 될 것입니다.
밥 - 더 - 구축함

3
SERVER_NAME반드시 서버에 의해 제어되는 것은 아닙니다. 게이트웨이 및 설정에 따라 중복 될 수 있으므로 HTTP_HOST동일한주의 사항이 적용됩니다.
bobince

1
@deceze @Rook SERVER_PORT그 작은 십자가가 필요 합니까 ? bugs.php.net/bug.php?id=64457
Dejan Marjanović

12

PHP에서로 $_SERVER시작하는 모든 변수 HTTP_는 사용자의 영향을받을 수 있습니다. 예를 들어, HTTP 요청에서 $_SERVER['HTTP_REINERS']HTTP 헤더 REINERS를 임의의 값 으로 설정 하여 변수 를 오염시킬 수 있습니다 .


다시 "임의"; 형식을 따르기 때문에 완전히 임의적이지는 않습니다. 예를 들어, $_SERVER['HTTP_REINERS'] 대부분의 sapi 아래에 개행 문자를 포함 할 수 없습니다.
Pacerier
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.