Не существует таких понятий, как «безопасные» или «небезопасные» ценности. Есть только значения, которые контролирует сервер, и значения, которыми управляет пользователь, и вам нужно знать, откуда берется значение и, следовательно, можно ли ему доверять для определенной цели. $_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также включает несколько переменных среды. Являются ли они «безопасными» или нет, зависит от того, как (и где) они определены. Они могут варьироваться от полностью контролируемых сервером до полностью управляемых пользователем.