АрхитектураАрхитектура безопасностиАрхитектор информационной безопасности

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

Как спроектировать журнал аудита так, чтобы компрометация сервиса не позволяла незаметно переписать историю событий?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Журнал аудита нужно вынести из зоны доверия самого сервиса и передавать события в отдельное хранилище с режимом добавления без изменения и удаления записей. Для обнаружения подмены применяют криптографически связанные записи или пакетные подписи, а доступ сервиса ограничивают только добавлением событий. Это не предотвращает компрометацию сервиса, но делает скрытое изменение уже записанной истории значительно сложнее и обнаруживаемым.

Исторический контекст

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

Для расследований инцидентов этого недостаточно: скомпрометированный процесс может удалить следы своих действий. Поэтому в системах, где важны доказуемость событий и контроль операций, журналирование отделяют от компонента, который генерирует события, и защищают целостность записей.

Постановка проблемы

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

Нужно защищать как минимум целостность, порядок и доступность аудита. При этом следует учитывать, что журнал не доказывает истинность события автоматически: он фиксирует утверждение источника, а не обязательно независимый факт.

Подробное решение

Сервис должен отправлять события в отдельный компонент аудита по защищённому каналу. Его учётная запись получает минимальное право: добавлять записи, но не изменять и не удалять уже принятые события. Чтение и администрирование выполняются другими ролями и отдельно журналируются.

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

Хранилище должно поддерживать режим неизменяемого хранения с заданным сроком удержания, например объектную блокировку или специализированный append-only-журнал. Резервные копии должны находиться отдельно от основной зоны компрометации, иначе атакующий может уничтожить и журнал, и его копии.

Событие обычно содержит время, источник, субъект или идентификатор сессии, действие, объект, результат и корреляционный идентификатор. Время из одного сервиса нельзя считать абсолютно надёжным, поэтому используют синхронизацию часов и фиксируют сервер-источник; для расследования важнее также последовательность и взаимная корреляция событий.

Есть компромиссы. Синхронная запись повышает гарантию сохранения аудита, но увеличивает задержку и может сделать доступность приложения зависимой от системы журналирования. Асинхронная отправка дешевле по задержке, однако при сбое возможна потеря буфера; это нужно компенсировать локальной очередью, контролем переполнения и явной политикой отказа.

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

Ситуация из практики

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

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

Выбрали отдельный сервис аудита с правом только добавления, неизменяемым хранилищем, подписанными пакетами событий и локальной очередью ограниченного размера. Для критичных отмен включили режим отказа операции при невозможности подтвердить приём аудита, а для некритичных событий оставили асинхронную доставку с мониторингом потерь.

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

Что кандидаты часто упускают

  1. Достаточно ли цепочки хешей, чтобы журнал считался защищённым?

Нет. Цепочка хешей обнаруживает изменение или удаление записи только при наличии доверенной исходной точки и сохранённого последнего контрольного значения. Если атакующий может переписать весь журнал вместе с начальным значением, внутренняя последовательность снова будет выглядеть корректной. Поэтому контрольные значения периодически фиксируют во внешней системе, подписывают ключом вне зоны приложения или используют неизменяемое хранилище.

  1. Что делать, если скомпрометированный сервис перестал отправлять события?

Защита целостности не решает проблему полноты аудита. Нужно контролировать ожидаемый поток событий: проверять heartbeat, последовательность номеров, задержку доставки и расхождение между бизнес-операциями и аудиторскими записями. Для особо критичных действий решение может быть принято только после подтверждения приёма события системой аудита; это повышает безопасность, но снижает доступность при её сбое.

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

Не всегда. Журнал может зафиксировать запрос, который отправил скомпрометированный процесс, украденная сессия или администратор с подменённой идентичностью. Для более сильного вывода нужно связывать событие с результатом операции, источником аутентификации, идентификатором сессии, подтверждением пользователя и независимыми системными событиями. Даже тогда журнал обеспечивает свидетельство и целостность истории, но не абсолютную гарантию истинности каждого поля.