Бухгалтер с правами «только для чтения» мог отменять счета и удалять историю платежей в инструменте для ведения бухгалтерии с открытым исходным кодом Akaunting, подвергая малый бизнес риску скрытой потери данных. Уязвимость была исправлена в версии 3.2.0, но сама ошибка — привязка проверок разрешений к жестко заданному списку имен методов — по-прежнему представляет угрозу для любой системы, полагающейся на управление доступом на основе ролей.

Как пропустили баг

API Akaunting проверяет права пользователя, обращаясь к «белому списку» (allowlist) имен методов. Список охватывал стандартные операции CRUD — create, read, update, delete — но в нем отсутствовали несколько эндпоинтов, изменяющих статус:

  • markSent
  • markCancelled
  • markReceived

Поскольку этих обработчиков не было в списке, фреймворк не вызывал процедуру проверки разрешений при их выполнении. Пользователь с ролью «только для чтения» мог отправить простой GET-запрос к эндпоинту markCancelled, и система воспринимала бы это как легитимное изменение состояния.

Отмена счета делает больше, чем просто помечает документ как недействительный; она также удаляет все записи о платежах, связанные с этим счетом. Результат: пользователь без прав на редактирование может уничтожить финансовый след транзакции.

Что показало тестирование

Уязвимость была обнаружена в официальном Docker-образе Akaunting:

  • Стандартный PUT-запрос для обновления счета возвращал 403 Forbidden, что подтверждало защиту обычного пути обновления.
  • GET-запрос к эндпоинту отмены прошел успешно без ошибки авторизации, выявив брешь.

Почему это важно

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

Исправление

В версии 3.2.0 карта разрешений расширена и теперь включает ранее пропущенные действия со статусами. Начиная с этого релиза, любой запрос, изменяющий состояние документа — будь то отметка об отправке, отмене или получении — должен проходить ту же проверку ролей, что и стандартное обновление. Это восстанавливает ожидаемое поведение, при котором роль «только для чтения» действительно не может изменять данные.

Уроки для разработчиков

  • Никогда не приравнивайте имена методов к безопасности. Добавление нового эндпоинта не означает автоматическое наследование защиты; проверяйте каждый публичный метод на наличие побочных эффектов.
  • Белые списки хороши лишь настолько, насколько полон сам список. Статический список «правильных» глаголов оставляет дверь открытой для недосмотров.
  • Отделяйте намерение от HTTP-метода. GET предназначен только для чтения, но в данном случае он изменил состояние. Ограничьте мутации методами POST, PUT, DELETE, PATCH.
  • Автоматизируйте проверку покрытия разрешений. Инструменты статического анализа могут помечать методы контроллеров, в которых отсутствует вызов авторизации, выявляя пробелы до релиза.
  • Тестируйте с использованием учетных записей с минимальными привилегиями. Тест на базе Docker использовал пользователя с правами «только для чтения»; воспроизведение таких сценариев в CI-конвейерах позволяет выявлять подобные проблемы на ранних этапах.

На что обратить внимание

Сообщество Akaunting уже выпустило исправленную версию. Администраторам следует проверить версию своего экземпляра и незамедлительно применить обновление.

Для разработчиков, создающих любые системы на основе ролей, вывод очевиден: модель разрешений, зависящая от необходимости помнить о каждом возможном действии, по своей сути хрупка. Явно объявляйте, какие операции изменяют состояние, внедряйте проверки на уровне фреймворка и регулярно проводите аудит кодовой базы. Только тогда можно будет доверять метке «только для чтения» в вопросе сохранности финансовых записей.