Любая переменная, которую пользователь может контролировать, злоумышленник также может контролировать и, следовательно, является источником атаки. Это называется «испорченной» переменной и небезопасно.
При использовании $_SERVER можно контролировать многие переменные. PHP_SELF , HTTP_USER_AGENT , HTTP_X_FORWARDED_FOR , HTTP_ACCEPT_LANGUAGE и многие другие являются частью заголовка HTTP-запроса, отправленного клиентом.
Кто-нибудь знает «безопасный список» или незанятый список переменных $_SERVER ?
Таких вещей, как «безопасные» или «небезопасные» ценности, не существует. Существуют только значения, которые сервер контролирует и значения, которые пользователь контролирует, и вам нужно знать, откуда приходит значение, и, следовательно, можно ли им доверять в определенной цели. $_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#usecanicalphysicalport , http: //httpd.apache. орг / документы / 2.4 / мод / 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 также включает в себя несколько переменных среды. Являются ли они «безопасными» или не зависят от того, как (и где) они определены. Они могут варьироваться от полностью контролируемого сервера до полностью управляемого пользователем.
В PHP на каждую переменную $_SERVER начинающуюся с HTTP_ может влиять пользователь. Например, переменная $_SERVER['HTTP_REINERS'] может быть испорчена, установив HTTP-заголовок REINERS произвольным значением в HTTP-запросе.