Что представляет собой суперглобальный массив $_REQUEST
в PHP, какие проблемы безопасности связаны с его использованием и почему его следует избегать в современной разработке?
$_REQUEST
— суперглобальный массив, объединяющий данные $_GET
, $_POST
и $_COOKIE
. Опасен из-за неопределенности источника данных. Не рекомендуется к использованию — всегда указывайте явный источник ($_GET
/$_POST
) для безопасности.
Полный ответ:
1. Основное назначение
$_REQUEST
— это суперглобальный ассоциативный массив, который объединяет данные из $_GET
, $_POST
и $_COOKIE
по умолчанию.
Содержимое:
// URL: page.php?name=John
// Форма POST: email=john@example.com
// Куки: theme=dark
print_r($_REQUEST);
// Array(
// 'name' => 'John', // из $_GET
// 'email' => 'john@example.com', // из $_POST
// 'theme' => 'dark' // из $_COOKIE
// )
2. Порядок объединения данных
Порядок определяется директивой request_order
или variables_order
в php.ini:
По умолчанию:
; Обычный порядок: GPС (GET, POST, COOKIE)
variables_order = "GPCS"
Приоритет: Последний источник в порядке имеет приоритет при конфликте имен.
// Если есть одинаковые имена:
// $_GET['name'] = 'John'
// $_POST['name'] = 'Jane'
// $_COOKIE['name'] = 'Bob'
echo $_REQUEST['name']; // 'Jane' (POST имеет приоритет над GET)
3. Проблемы безопасности
Главная опасность — неопределенность источника:
// НЕПОНЯТНО: откуда пришел параметр?
$action = $_REQUEST['action'];
// Это может быть:
// - GET: /page.php?action=delete
// - POST: скрытая форма
// - COOKIE: поддельная кука
Обход проверок:
// Разработчик ожидает POST:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = $_POST['id']; // Думает, что безопасно
}
// Но атакующий может передать через GET:
// /page.php?id=1' OR '1'='1
// И если используется $_REQUEST['id'] - получит уязвимость
4. Изменение порядка источников
Порядок можно изменить через php.ini:
; Только GET и POST (без COOKIE)
request_order = "GP"
; Свой порядок
request_order = "PG" // POST имеет приоритет над GET
5. Практические риски
CSRF-уязвимости:
// ОПАСНО: использование $_REQUEST для критических действий
if (isset($_REQUEST['delete_user'])) {
deleteUser($_REQUEST['user_id']); // Можно вызвать через GET!
}
// БЕЗОПАСНО: явное указание источника
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_user'])) {
deleteUser($_POST['user_id']);
}
Подмена данных:
// Пользователь может установить куку с именем параметра формы
// и подменить значение, даже если форма не отправлялась
6. Best Practices — КОГДА НЕ ИСПОЛЬЗОВАТЬ
Избегайте $_REQUEST
для:
- Критических операций (удаление, изменение данных)
- Авторизации и аутентификации
- Любых действий с побочными эффектами
Допустимые случаи:
- Параметры фильтрации/поиска (где неважен источник)
- Настройки отображения
- Нефункциональные параметры
7. Явное указание источника
Всегда лучше использовать конкретный массив:
// ПЛОХО
$page = $_REQUEST['page'] ?? 1;
// ХОРОШО - явный источник
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$page = $_POST['page'] ?? 1;
} else {
$page = $_GET['page'] ?? 1;
}
// ИЛИ для разных сценариев
$searchTerm = $_GET['q'] ?? ''; // Поиск - через GET
$formData = $_POST['data'] ?? []; // Форма - через POST
$userPrefs = $_COOKIE['prefs'] ?? ''; // Настройки - через COOKIE
8. Современные альтернативы
Filter extension:
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?? 1;
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
PSR-7/HTTP-фундации:
В современных фреймворках используются объекты запроса с четким разделением источников.
9. Производительность
$_REQUEST
создает дополнительный overhead по сравнению с прямым использованием $_GET
/$_POST
.
Итог:
$_REQUEST
— суперглобальный массив, объединяющий $_GET
, $_POST
и $_COOKIE
. Ключевые проблемы:
- Неопределенность источника данных
- Потенциальные уязвимости безопасности (CSRF, подмена данных)
- Нарушение принципа наименьших привилегий
Рекомендация: В современной разработке избегайте использования $_REQUEST
. Всегда используйте явные источники ($_GET
, $_POST
, $_COOKIE
) для ясности и безопасности кода.