Любая переменная, которой может управлять пользователь, также может контролировать злоумышленник и, следовательно, является источником атаки. Это называется "испорченной" переменной и небезопасно.
При использовании $_SERVER
можно управлять многими переменными. PHP_SELF
, HTTP_USER_AGENT
, HTTP_X_FORWARDED_FOR
, HTTP_ACCEPT_LANGUAGE
И многие другие являются частью заголовка запроса HTTP , посланного клиентом.
Кто-нибудь знает о «безопасном списке» или незапятнанном списке $_SERVER
переменных?
REMOTE_ADDR
.HTTP_
является заголовком запроса и может быть установлено браузером или прокси-сервером между ними. Я бы рассмотрел их как любой другой пользовательский ввод.REMOTE_ADDR
. И это выходит за рамки этого вопроса. Хорошо, если вы разобрались, как устанавливается это значение, поэтому спасибо.Ответы:
Не существует таких понятий, как «безопасные» или «небезопасные» ценности. Есть только значения, которые контролирует сервер, и значения, которыми управляет пользователь, и вам нужно знать, откуда берется значение и, следовательно, можно ли ему доверять для определенной цели.
$_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
также включает несколько переменных среды. Являются ли они «безопасными» или нет, зависит от того, как (и где) они определены. Они могут варьироваться от полностью контролируемых сервером до полностью управляемых пользователем.источник
$_SERVER
значений в зависимости от того, как файл обслуживается. На мой взгляд, задокументированные не проясняют истинный источник. Иначе я думаю, вы бы не задавали этот вопрос. Рад, что у вас есть список, который вы можете использовать. Но я все же предлагаю отправить отчет об ошибке (когда их сайт с ошибкой будет исправлен), отправить разработчикам документации электронное письмо или обновить документы самостоятельно (если вы знакомы с ссылкой). Сообществу было бы полезно знать эту информацию.SERVER_NAME
не обязательно контролируется сервером. В зависимости от шлюза и настроек он может быть дублированHTTP_HOST
и, следовательно, с той же оговоркой.SERVER_PORT
этот крестик нужен? bugs.php.net/bug.php?id=64457В PHP каждая
$_SERVER
переменная, начинающаяся с,HTTP_
может зависеть от пользователя. Например, переменную$_SERVER['HTTP_REINERS']
можно испортить, установив для заголовка HTTPREINERS
произвольное значение в HTTP-запросе.источник
$_SERVER['HTTP_REINERS']
в большинстве sapis не может содержать символы новой строки.