PmaControl logo PmaControl
  • Главная
  • PmaControl
    • ИИ-агенты 13 on-premise агентов
    • Тарифы Community, Cloud, On-Premise, Premium
    • Документация Руководства, API, архитектура
    • Клиенты 28+ компаний
    • FAQ 25 вопросов / 7 категорий
    Базы данных
    • MariaDB 30 статей
    • MySQL 10 статей
    • Galera Cluster 6 статей
    • MaxScale 3 статьи
    • ProxySQL 2 статьи
    • Amazon Aurora MySQL 0 статьи
    • Azure Database 0 статьи
    • ClickHouse 0 статьи
    • GCP CloudSQL 0 статьи
    • Percona Server 0 статьи
    • SingleStore 0 статьи
    • TiDB 0 статьи
    • Vitess 0 статьи
    Решения
    • Поддержка 24×7 Экстренная помощь MariaDB & MySQL
    • Observabilité SQL Мониторинг, алерты, топология
    • Haute disponibilité Репликация, failover, Galera
    • Disaster Recovery Backup, restore, RPO/RTO
    • Sécurité & conformité Аудит, GDPR, SOC2
    • Migration & upgrade Zero downtime, pt-osc, gh-ost
  • Тарифы
  • Ресурсы
    • Документация Технические руководства и API
    • FAQ 25 частых вопросов
    • Отзывы Отзывы клиентов и кейсы
    • Блог Статьи и аналитика
    • Roadmap Планируемые функции
    Области экспертизы
    • Observabilité SQL Мониторинг, алерты, топология Dot3
    • Haute disponibilité Репликация, failover, Galera
    • Sécurité & conformité Аудит, GDPR, SOC2, ISO 27001
    • Disaster Recovery Backup, restore, RPO/RTO
    • Performance & optimisation Digests, EXPLAIN, tuning
    • Migration & upgrade Zero downtime, pt-osc
    Быстрые ссылки
    • Wiki GitHub 26 страниц — установка, движок, плагины
    • Исходный код Официальный репозиторий GitHub
    • Поддержка 24×7 Экстренная помощь MariaDB & MySQL
    • Записаться на демо 30 мин — реальная архитектура
  • Поддержка 24×7
  • Записаться на демо
Записаться на демо
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文
Документация › Protection CSRF (Origin + jeton scopé)

Protection CSRF (Origin + jeton scopé)

Зачем защищать POST

Без CSRF-токена, привязанного к сессии, сторонний сайт может отправить POST к PmaControl, пока аутентифицированный пользователь работает на другом сайте. Браузер автоматически прикладывает cookies сессии, и действие выполняется без воли пользователя — изменение конфигурации, запуск операции, inline-обновление.

Переход с GET на POST блокирует пассивные срабатывания (preload, индексирование), но не защищает от активной атаки CSRF с другого домена.

Общий хелпер Glial

Начиная с Glial v5.1.40, логика CSRF и валидация Origin/Referer вынесены во фреймворк и используются всеми контроллерами PmaControl:

  • Glial\Security\Csrf::issueToken() / Csrf::validateToken() — выдача и проверка токена по функциональному scope.
  • Glial\Http\Request::isSameSite() — сравнивает Origin (в приоритете), затем Referer (fallback) с текущим origin.
Ни один контроллер PmaControl не дублирует эту логику: Worker.php содержит только HTTP-оркестрацию, специфичную для POST /Worker/update.

Схема процесса

Схема механизма CSRF — выдача токена на сервере, вставка в HTML, AJAX-запрос, цепочка валидации из 4 шагов.
Схема механизма CSRF — выдача токена на сервере, вставка в HTML, AJAX-запрос, цепочка валидации из 4 шагов.

Выдача токена

Перед рендерингом представления с формой или inline-editable ячейкой контроллер выдаёт токен, привязанный к функциональному scope:

<?php
use Glial\Security\Csrf;

$token = Csrf::issueToken($_SESSION, 'worker.update');
$this->set('csrf_token', $token);
Scope не даёт токену, выданному для worker.update, быть повторно использованным на daemon.start. Токен хранится в $_SESSION['csrf_tokens'][$scope] и сохраняется до конца сессии пользователя.

Вставка на клиенте

Для inline-editable ячеек (bootstrap-editable) токен передаётся через два data-* атрибута:

<td class="editable"
    data-name="nb_worker"
    data-csrf-field="csrf_token"
    data-csrf-token="<?= htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8') ?>">
    5
</td>
Значения всегда экранируются через htmlspecialchars(..., ENT_QUOTES, 'UTF-8'), чтобы нейтрализовать любую HTML/JS-инъекцию в ячейке.

JS App/Webroot/js/Tree/index.js обнаруживает наличие data-csrf-token и автоматически добавляет токен в параметры POST, отправляемые bootstrap-editable:

$.fn.editable.defaults.params = function (params) {
    var $cell = $(this).closest('[data-csrf-token]');
    if ($cell.length) {
        params[$cell.data('csrf-field')] = $cell.data('csrf-token');
    }
    return params;
};
После AJAX-обновления (например, через Daemon) window.pmacontrolInitLineEdit(context) вызывается повторно для перезагруженного контекста, чтобы связать новый токен с новыми ячейками.

Цепочка валидации на сервере

Четыре проверки выполняются строго в этом порядке, до построения SQL:

  1. HTTP-метод — только POST; любой другой возвращает 405 Method Not Allowed.
  2. Same-site origin — сначала Origin, затем Referer как fallback; значения null, protocol-relative и с другим scheme/host/port отклоняются с 403 Invalid request origin.
  3. CSRF-токен — сравнение hash_equals() между полем csrf_token в payload и $_SESSION['csrf_tokens'][$scope]; отсутствующий или неверный токен возвращает 403 Invalid CSRF token.
  4. Allowlist payload — только ожидаемые поля и типы для этого endpoint; payload вне списка возвращает 400 Invalid worker update payload.
<?php
class Worker
{
    public function update()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            http_response_code(405);
            return;
        }
        if (!Glial\Http\Request::isSameSite($_SERVER)) {
            http_response_code(403);
            echo 'Invalid request origin';
            return;
        }
        if (!Glial\Security\Csrf::validateToken($_POST, $_SESSION, 'worker.update')) {
            http_response_code(403);
            echo 'Invalid CSRF token';
            return;
        }

        $sql = $this->buildWorkerUpdateSql($_POST);
        if ($sql === null) {
            http_response_code(400);
            echo 'Invalid worker update payload';
            return;
        }

        // SQL exécuté ici uniquement
    }
}
Пока не пройдут все четыре проверки, SQL не строится: защита в глубину работает, даже если один из барьеров будет обойдён.

Справочник — коды возврата

Код Причина Когда
405 Method Not Allowed HTTP-метод, отличный от POST.
403 Invalid request origin Origin/Referer вне сайта, Origin: null, protocol-relative или другой scheme/host/port.
403 Invalid CSRF token Токен отсутствует в payload или не совпадает с $_SESSION['csrf_tokens'][$scope].
400 Invalid worker update payload Поле вне allowlist, нецелое значение, отрицательный или нулевой pk.
Никогда не давайте мутирующему endpoint fallback на GET «для отладки»: это незаметно отключит защиту CSRF, которая работает только на POST.

Документированные исключения

Хелпер CSRF покрывает только web-POST. Следующие поверхности явно исключены:

  • CLI php glial … — нет cookie сессии, нет CSRF-поверхности.
  • REST API machine-to-machine — аутентификация отдельным API-токеном; проверка Origin/Referer отключена для этих маршрутов, исключение документируется по endpoint.
  • Read-only endpoints — переведены на GET и потому вне периметра CSRF.

Выделенные тесты

Защита CSRF покрыта тестами PHPUnit, которые явно воспроизводят исторический сценарий атаки:

./vendor/bin/phpunit tests/Glial/Security/CsrfTest.php
./vendor/bin/phpunit tests/Glial/Http/RequestTest.php
./vendor/bin/phpunit tests/Controller/WorkerUpdateSecurityTest.php
С Origin: https://attacker.test или любым другим внешним сайтом payload отклоняется с 403 Invalid request origin до любой записи, даже если предоставлен валидный CSRF-токен — цепочка валидации останавливается на Origin до проверки токена.
На этой странице
  • Зачем защищать POST
  • Общий хелпер Glial
  • Схема процесса
  • Выдача токена
  • Вставка на клиенте
  • Цепочка валидации на сервере
  • Справочник — коды возврата
  • Документированные исключения
  • Выделенные тесты
← Предыдущая страница Следующая страница →
PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
Юридическая информация GitHub Контакты
Не ждите инцидента, чтобы понять свою архитектуру. © 2014-2026 PmaControl — 68Koncept