Любая переменная, которую пользователь может контролировать, злоумышленник также может контролировать и, следовательно, является источником атаки. Это называется «испорченной» переменной и небезопасно.
При использовании $_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-запросе.