Небезопасный кеш данных

Автор:

LastTeamLead

Кеширование данных – штука полезная для скорости работы и оптимизации. Но часто кеш преподносит сюрпризы, если с ним напортачить или что-то не предусмотреть. Можно нарваться на невалидные или неактуальные данные, когда происходит коллизия ключей или случаются проблемы в механизмах очистки, актуализации или времени жизни кеша. И еще много других вариаций проблем и ошибок. Ничего нового: как и с любым другим инструментом, с кешированием нужно работать обдуманно.

Небезопасный кеш данных

Но иногда проблемы могут появиться там, где их совсем не ждешь, – в таких местах, которые незаметны, однако очень критичны, вплоть до угрозы безопасности всей системы. Так и случилось недавно на одном из рабочих проектов. Проблему удалось заметить и исправить еще до релиза, но история может быть поучительной и полезной.

Делали админку для сервиса на Laravel – простенький CRUD данных. Для ускорения разработки взяли готовый Backpack и накатили его модули для управления ролями: у пользователей несколько уровней доступа – админ и пара обычных пользователей разных уровней. Модуль Backpack для ролей называется PermissionManager, вот ссылка на его репозиторий: GitHub.

В админке, кроме CRUD для контента, добавили и раздел управления ролями, где можно назначать и снимать привилегии доступа. Сделали без лишних кастомизаций, используя логику того же модуля PermissionManager. Всё быстро собралось и запустилось. Но при тестировании поймали баг: после удаления админских прав у пользователя всё еще оставались его полномочия. Роль админа оставалась доступна до тех пор, пока пользователь не разлогинится и не залогинится обратно.

Данные в БД и сессии обновлялись правильно, но пользователь всё еще имел пометку админа при запросе его роли. Кеширование роли мы не добавляли, а в документации админки и модуля ролей про это ничего не нашли.

Немного покопавшись в модуле, обнаружили, что он сам использует дополнительные библиотеки для работы с ролями – PermissionRegistrar из пакета Spatie. И уже в документации от Spatie нашли, что роли кешируются и работают через стандартные конфиги Laravel. А у нас в проекте используется Redis для кеша запросов к БД. Время кеша по умолчанию – 24 часа. И этот кеш сам не очищается при обновлении ролей, его нужно принудительно чистить, так как библиотека обновление не производит. Также очистка кеша не реализована и в модуле PermissionManager.

Видимо, в таком подходе к кешированию ролей была какая-то логика, но явно про нее нигде не указано. В репозитории PermissionManager есть свежий коммит с подозрительным названием «Fix reset cache», и это единственное упоминание кеша ролей от Backpack.

То есть, если бы на этапе тестирования проблема не была обнаружена, то можно было зарелизить сервис, который отзывает роли админов с задержкой в 24 часа. А за сутки некоторые вредители могут много дел натворить. Мораль простая: нужно хорошо понимать инструменты, которые используешь, а сторонние решения всегда предварительно хорошенько изучать.

P.S. Если кому-то нужен фикс, то очистка кеша ролей в модуле PermissionManager от Backpack вызывается так (использовать после обновления или удаления ролей пользователя):

Также по теме:

Небезопасный кеш данных

/Код-ревью

Небезопасный кеш данных

Кеширование данных – штука полезная для скорости работы и оптимизации. Но часто кеш преподносит сюрпризы, если с ним напортачить или что-то не предусмотреть.
Прочитать

7

0

Приколы с алгоритмом Bcrypt для создания хешей

/Код-ревью

Приколы с алгоритмом Bcrypt для создания хешей

Если не знать нюансов работы Bcrypt, можно получить проблемы с безопасностью даже при использовании соли и хеширования. В материале — разбор уязвимости на конкретном примере
Прочитать

5

0