Які змінні $ _SERVER є безпечними?


97

Будь-яка змінна, якою користувач може керувати, зловмисник також може керувати і тому є джерелом атаки. Це називається "заплямованою" змінною і небезпечно.

При використанні $_SERVERможна керувати багатьма змінними. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGEІ багато інших є частиною заголовка запиту HTTP , посланого клієнтом.

Хто-небудь знає про "безпечний список" або не збережений список $_SERVERзмінних?


8
Залежить від того, як ви визначаєте "безпечний". Цінні значення всі безпечні, як вони є, залежить лише те, для чого ви їх використовуєте.
деге

6
Я думаю, що в цьому контексті Рок говорить "Які серверні змінні не можуть бути підроблені користувачем", наприклад REMOTE_ADDR.
vcsjones

6
Все, що має попереднє значення, HTTP_є заголовком запиту, і його можна встановити між браузером або проксі. Я вважаю, що це будь-який інший користувальницький вклад.
передача даних

3
@ bob-the-знищувач REMOTE_ADDR витягується безпосередньо з TCP-розетки apache, це значення не можна підробляти через Інтернет через тривимірне рукостискання.
грак

2
@Rook: хороший момент. Я думаю, згадуючи "підробку", я більше схилявся до старого акта підроблення самого ip, а не до якогось фальсифікації фактичного значення REMOTE_ADDR. І це було б поза рамками цього питання. Добре ознайомитись із тим, як встановлено це значення, тому дякую.
боб-

Відповіді:


147

Не існує таких понять, як "безпечні" чи "небезпечні" значення як такі. Є лише ті значення, якими керує сервер, і значення, якими керує користувач, і вам потрібно знати, звідки походить значення, а отже, чи можна йому довіряти певну мету. $_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включає також кілька змінних середовищ. Чи є вони "безпечними" чи не залежать від того, як (і де) вони визначені. Вони можуть варіюватися від повністю керованого сервера до повністю керованого користувачем.


3
@Rook Але, як я вже сказав, це абсолютно залежить від того, як ви ним користуєтесь . Цінності самі по собі не є ні безпечними, ні небезпечними, це залежить від того, для чого ви їх використовуєте . Навіть дані, надіслані від шкідливого користувача, абсолютно безпечні, якщо ви нічого не робите з цим, що може загрожувати вашій безпеці.
деге

2
@Rook: ваше уявлення про "безпечний" робить це питання здається дещо довільним, тим більше, що він повністю пов'язаний з неясним розширенням або спеціальною версією PHP. Хоча ви говорите, що "не повинно бути" підстрілу з стегна "підходу", але будь-яка відповідь насправді вимагає мінімального ознайомлення з вихідним кодом PHP, щоб дізнатися, як ці значення встановлені. Чи не надсилати електронну пошту PHP розробникам кращим підходом до пошуку відповіді?
боб-

2
@Rook: комунікація. Як надумав наголос, "безпечно з якою метою". Як я натякав, ваше призначення невідоме, і крім того, існує кілька інших недокументованих $_SERVERзначень, залежно від того, як файл подається. На мою думку, задокументовані не з’ясовують справжнє джерело. Інакше я вважаю, що ви б не ставили цього питання. Радий, що у вас є список, який ви можете використовувати. Але я б все-таки запропонував надіслати звіт про помилку (коли виправлено їхній веб-сайт про помилки), надіслати електронний лист, який обслуговує документи, або оновити документи самостійно (якщо вам відомо про посилання). Було б корисно громаді знати цю інформацію.
боб-

3
SERVER_NAMEне обов'язково контролюється сервером. Залежно від шлюзу та налаштувань, він може бути продубльований HTTP_HOSTі, отже, підпадає під один і той самий застереження.
bobince

1
@deceze @Rook Чи SERVER_PORTпотрібен цей маленький хрестик? bugs.php.net/bug.php?id=64457
Деян

12

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


повторно "довільне"; Не всі довільні, оскільки вони відповідають формату. Наприклад, $_SERVER['HTTP_REINERS'] не може містити символи нового рядка під більшістю сапісів.
Pacerier
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.