SLOT-H: Динамическая подпись
В системе реализован механизм динамической подписи для защиты запросов от CSRF-атак и подмены данных. Подпись генерируется на сервере и передаётся на фронтенд, а затем возвращается с каждым запросом для верификации.
Принцип работы
При каждом запросе сервер генерирует уникальную подпись и сохраняет её в сессии. Подпись передаётся на фронтенд в составе ответа. При отправке следующего запроса фронтенд обязан передать эту подпись обратно. Сервер сравнивает полученную подпись с той, что хранится в сессии.
Если подписи совпадают - запрос считается валидным. Если подпись отсутствует или не совпадает - запрос отвергается.
Подпись обновляется при каждом запросе, что делает невозможным повторное использование старой подписи.
Хранение
Подпись хранится в сессии пользователя. Для её получения и обновления используется объект `Request`:
php
self::_VERIFY_ = 'verifyHash';
$_SESSION[self::_VERIFY_] = md5(time() . rand(1000, 9999));
На фронтенд подпись передаётся в поле sign ответа. Для API-запросов подпись добавляется в тело ответа автоматически.
Передача подписи на фронтенд
Подпись передаётся в ответе сервера в поле sign. Для веб-страниц подпись автоматически добавляется в сессию и доступна через механизмы фронтенда. Для API-запросов подпись включается в JSON-ответ.
Пример ответа API:
json
{
"status": "data",
"data": {...},
"message": false,
"sign": "f8cbc97de21289267b415a035419897b"
}
Фронтенд извлекает подпись из ответа и сохраняет её для следующего запроса.
Проверка подписи
Проверка выполняется в классе Request при обработке входящего запроса. Для POST-запросов проверяется наличие поля _sign_ и его соответствие значению в сессии.
php
if (!isset($_REQUEST['_sign_']) || $_SESSION[self::_VERIFY_] != $_REQUEST['_sign_']) {
// подпись невалидна - запрос отвергается
}
В случае невалидной подписи все параметры запроса обнуляются, а запрос считается недействительным.
Обновление подписи на фронтенде
При загрузке страницы подпись передаётся как значение js-переменной alfaFooter. Любой API-запрос (включая плановый пинг) получает в ответе актуальную подпись и обновляет alfaFooter.
Таким образом, максимальное время жизни подписи ограничено 30 секундами - периодом планового пинга. При этом подпись может обновляться чаще, если действие пользователя инициирует другой API-запрос.
Отключение проверки
Проверка подписи может быть отключена через конфигурацию:
php
define('IGNORE_SIGN', true);
Этот флаг используется в режиме разработки, когда необходимо упростить тестирование. В боевом режиме IGNORE_SIGN должен быть false.
Важно: отключение проверки подписи снижает защиту системы и не рекомендуется для production-среды.
Особенности реализации
Механизм подписи позволяет защитить систему от CSRF-атак без необходимости использовать дополнительные библиотеки и усложнять код. Он встроен в ядро системы и работает автоматически для всех POST-запросов.
Для GET-запросов проверка подписи не выполняется, так как они не изменяют состояние системы.
Подпись не зависит от пользователя напрямую - она привязана к сессии, что делает её защищённой от подмены. При смене сессии (перелогинивании) подпись пересоздаётся автоматически.
Что дальше?
- ➡️ Раздел 25. Защита доступа
- ➡️ Раздел 26. Принцип локализации
- ➡️ Раздел 27. Запуск сервера очередей