Какие переменные $SERVER безопасны?


Любая переменная, которой может управлять пользователь, также может управляться злоумышленником и, следовательно, является источником атаки. Это называется "испорченной" переменной и небезопасно.

При использовании $_SERVER, многими переменными можно управлять. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGE и многие другие являются частью заголовка HTTP-запроса, отправляемого клиентом.

Кто-нибудь знает о "безопасном списке" или незапятнанном списке переменных $_SERVER?

Author: Benjol, 2011-06-25

2 answers

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

 134
Author: deceze, 2017-05-23 12:10:24

В PHP каждая переменная $_SERVER, начинающаяся с HTTP_, может зависеть от пользователя. Например, переменная $_SERVER['HTTP_REINERS'] может быть изменена путем установки заголовка HTTP REINERS в произвольное значение в HTTP-запросе.

 10
Author: Reiners, 2012-06-05 11:12:42