Внимание! Дистрибутив RK-CMS распространяется исключительно через сайт rk-cms.ru. Загрузка копий со сторонних ресурсов может привести к потере данных или установке вредоносного ПО.

Меню
    300 140

    В мире веб-разработки есть классическая задача: как защитить пользователя от атаки, которую он совершает собственными руками, даже не подозревая об этом. Речь идет о CSRF (Cross-Site Request Forgery) или "межсайтовой подделке запроса".

    Большинство систем решают эту проблему стандартно: выдают каждому пользователю секретный код (токен) и заставляют предъявлять его при каждом действии. Но в RK-CMS мы пошли другим путем. Мы просто спрятали сами двери.

    Давайте разберемся, как это работает и почему хранение "ключей" в печеньках (куках) - это не всегда хорошая идея.

    Классическая проблема: Ты сам приносишь грабителю ключ

    Представьте классический интернет-магазин. Пользователь Вася залогинился. Сервер дал его браузеру "пропуск" (куку сессии), чтобы Вася не вводил пароль заново на каждой странице.

    Теперь представьте, что Вася перешел на "злую" страницу в интернете. На этой странице спрятан JavaScript-код, который пытается отправить запрос в интернет-магазин. Например, "перевести все деньги на счет хакера".

    Браузер Васи видит запрос к знакомому сайту и автоматически подставляет туда "пропуск" Васи из кук. Сервер магазина видит: запрос пришел с правильным пропуском. Значит, это Вася. Деньги ушли.

    В чем суть атаки? Браузер не понимает, что команду отдал не Вася, а вредоносный код на другом сайте. Вася стал марионеткой.

    Стандартное решение: CSRF-токен (Пароль на каждое действие).

    Чтобы отличить "настоящего Васю" от "кукловода", разработчики придумали CSRF-токены.

    Это работает так:

    Вася заходит на страницу перевода денег.

    Сервер генерирует секретный набор символов (токен) и вшивает его прямо в HTML-код страницы (в скрытое поле формы).

    Вася нажимает кнопку "Перевести".

    Запрос уходит вместе с этим токеном.

    Злой сайт не может прочитать этот токен (из-за политики браузера), поэтому его запрос будет отвергнут.

    Но есть нюанс: Часто разработчики для удобства кладут этот токен в Cookie.

    Вот тут и кроется ловушка, о которой мы говорим.

    Почему хранить CSRF-токен в Cookie - плохая идея?

    Если мы кладем ключ защиты в куку, мы возвращаемся к исходной точке.

    Злой сайт отправляет запрос.

    Браузер автоматически прикрепляет к запросу все куки для этого домена. И сессию, и ваш CSRF-токен.

    Сервер смотрит: "Ага, сессия на месте, и CSRF-токен на месте. Все сходится!".

    Атака проходит успешно.

    Вывод: CSRF-токен в куке - это как положить ключ от сейфа под коврик прямо возле двери. Формально замок есть, но пользы от него ноль. В этом случае токен просто повторяет путь сессии и не доказывает, что действие совершил именно человек, кликнувший мышкой, а не скрипт.

    Сценарий с мессенджером: почему SameSite=Lax не спасает

    Многие сейчас говорят: "Мы храним CSRF-токен в куке, но ставим SameSite=Lax, так что при POST-запросах куки не уйдут". Это правда, но есть одна лазейка.

    Представь: злоумышленник пишет тебе в Telegram или WhatsApp сообщение: "Смотри, какая смешная картинка!" и прикрепляет ссылку. Но ссылка ведёт не на картинку, а на адрес в админке, который выполняет действие через GET-запрос. Например:

    https://site.com/admin/transfer?to=hacker&amount=1000

    Ты кликаешь по ссылке, браузер открывает её как обычный переход. SameSite=Lax разрешает отправку кук для навигации (GET). В результате браузер прикрепит к запросу все куки, включая сессионную и, если она там лежит, CSRF-токен. Сервер увидит валидную сессию, валидный токен (ведь они оба пришли из кук) и выполнит перевод. Ты даже не поймёшь, что произошло и увидишь лишь страницу с ошибкой или пустую страницу, а деньги уже ушли.

    В этом и заключается опасность: если действие можно выполнить через GET, то SameSite=Lax не поможет, потому что он пропускает GET-запросы. А хранение CSRF-токена в куке делает атаку ещё проще: злоумышленнику даже не нужно угадывать или воровать токен, он сам приедет вместе с запросом.

    В RK-CMS такая атака невозможна, потому что URL действия содержит секретный префикс. Злоумышленник не может угадать этот префикс, а без него сервер вернёт 404. Даже если он заставит пользователя перейти по ссылке, она окажется нерабочей. Именно поэтому мы не полагаемся на куки и SameSite, а делаем сами адреса непредсказуемыми.

    Подход RK-CMS: У каждой двери свой адрес (Уникальный URL)

    В RK-CMS мы решили отказаться от погони за токенами и "секретными словами". Мы используем динамическую маршрутизацию с секретным префиксом.

    Как это выглядит на практике?

    В обычной CMS ссылка на удаление статьи выглядит так:

    /admin/posts/delete/123

    Все знают этот адрес. Хакеру остается только заставить браузер жертвы перейти по нему.

    В RK-CMS все иначе. Для каждого пользователя в рамках его сессии мы генерируем уникальный секретный префикс.

    Ссылка выглядит примерно так:

    /aB3xZ9qL/admin/posts/delete/123

    А у другого пользователя (или в другой сессии) она будет:

    /Kd8sNf2p/admin/posts/delete/123

    Почему это работает?

    Неизвестность адреса (Security through Obscurity в хорошем смысле):
    Злоумышленник не знает, какой именно секретный префикс присвоен текущей сессии пользователя Васи. Он может знать, что нужно удалить пост 123, но он не знает полный URL.

    Раньше: Он мог послать запрос на /admin/posts/delete/123.

    Сейчас: Он пошлет запрос на этот адрес и получит ответ 404 Not Found (Не найдено), потому что правильный адрес содержит секретный ключ.

    Кука тут не поможет:

    Хакер не может вытащить этот префикс из Cookie, потому что мы его туда принципиально не кладем. Префикс существует только в HTML-коде страницы, который хакер прочитать не может.

    Защита от Clickjacking (Кликджекинга):

    Часто атака заключается в том, что поверх легитимного сайта кладут прозрачный iframe, и пользователь думает, что кликает по кнопке "Выиграть приз", а на самом деле кликает по кнопке "Удалить аккаунт".
    В нашем случае, даже если злоумышленник загрузит наш сайт в iframe, он не сможет угадать URL с секретным префиксом, чтобы загрузить нужную страницу с опасной кнопкой.

    Итог: Проще, но надежнее.

    Подход RK-CMS ломает шаблон. Вместо того чтобы добавлять в систему дополнительную сущность (токен) и следить за ее синхронизацией, мы сделали саму систему адресов непредсказуемой.

    Мы не даем пользователю "открытку", которую можно украсть из браузера (Cookie). Мы просто выдаем ему координаты секретной двери, которые знает только он один в данный момент времени.

    Плюсы подхода:

    Нет ложного чувства безопасности: Мы не имитируем защиту, храня ключи в общедоступном месте (в куках).

    Простота реализации: Не нужно генерировать, валидировать и хранить миллионы токенов для каждой формы.

    Надежность: Хакер физически не может подделать запрос, потому что не знает точку назначения.

    В RK-CMS мы считаем, что защита должна быть прагматичной.

    Для улучшения работы сайта и его взаимодействия с пользователями мы используем файлы cookie (узнать подробнее).

    Продолжая работу с сайтом, Вы разрешаете использование cookie-файлов. Вы всегда можете отключить файлы cookie в настройках Вашего браузера.