Ответ 1
Нет таких вещей, как "безопасные" или "небезопасные" значения как таковые. Существуют только значения, которые сервер контролирует и значения, которые пользователь контролирует, и вам нужно знать, откуда приходит значение, и, следовательно, можно ли им доверять в определенной цели. $_SERVER['HTTP_FOOBAR']
, например, полностью безопасно хранить в базе данных, но я, безусловно, не был бы eval
.
Таким образом, разделим эти значения на три категории:
Управляемый сервером
Эти переменные устанавливаются средой сервера и полностью зависят от конфигурации сервера.
-
'GATEWAY_INTERFACE'
-
'SERVER_ADDR'
-
'SERVER_SOFTWARE'
-
'DOCUMENT_ROOT'
-
'SERVER_ADMIN'
-
'SERVER_SIGNATURE'
Частично контролируемый сервер
Эти переменные зависят от конкретного запроса, отправленного клиентом, но могут принимать только ограниченное число допустимых значений, так как все недопустимые значения должны быть отклонены веб-сервером и не должны вызывать обращение к script. Следовательно, их можно считать надежными.
-
'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
также включает в себя несколько переменных среды. Являются ли они "безопасными" или не зависят от того, как (и где) они определены. Они могут варьироваться от полностью контролируемого сервера до полностью управляемого пользователем.