Какие переменные $_SERVER безопасны?
Любая переменная, которой может управлять пользователь, также может контролировать злоумышленник и, следовательно, является источником атаки. Это называется "испорченной" переменной и небезопасно.
Когда используешь $_SERVER
многие из переменных можно контролировать. PHP_SELF
, HTTP_USER_AGENT
, HTTP_X_FORWARDED_FOR
, HTTP_ACCEPT_LANGUAGE
и многие другие являются частью заголовка HTTP-запроса, отправляемого клиентом.
Кто-нибудь знает "безопасный список" или незапятнанный список $_SERVER
переменные?
2 ответа
Нет такой вещи как "безопасные" или "небезопасные" ценности как таковые. Существуют только значения, которыми сервер управляет, и значения, которые контролирует пользователь, и вам необходимо знать, откуда берется значение и, следовательно, можно ли ему доверять для определенной цели. $_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'
* The 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, http://httpd.apache.org/docs/2.4/mod/core.html
Полностью произвольные контролируемые пользователем значения
Эти значения вообще не проверяются и не зависят от какой-либо конфигурации сервера, это полностью произвольная информация, отправляемая клиентом.
'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.