Мы сталкиваемся с распространенной, но крайне неприятной ситуацией: в базе 1С8.3 эпизодически удаляются документы, а Журнал регистрации (ЖР) при этом остается чистым. Это может указывать на то, что злоумышленник отключает регистрацию событий, использует внешние обработки, запускаемые со своего компьютера, или имеет полные административные права, позволяющие обойти стандартные механизмы контроля. База опубликована, находится на полной поддержке, внешние отчеты и обработки не добавлены в конфигурацию, а пользователи работают через тонкий клиент по вебу. Наша задача — обнаружить виновника с поличным. Давайте разберем по шагам, какие действия мы можем предпринять для выявления и предотвращения несанкционированного удаления документов.
Первоочередная мера — это аудит и ужесточение прав доступа пользователей. Большинство несанкционированных действий, которые обходят Журнал регистрации, возможны только при наличии у пользователя расширенных прав.
Открытие внешних отчетов и обработок для всех пользователей, кроме тех, кому она действительно необходима (например, для запуска проверенных администратором служебных обработок). Запуск внешних обработок — это один из наиболее распространенных способов, позволяющих выполнять операции (в том числе удаление документов) без фиксации в стандартном Журнале регистрации.Мы не должны забывать о стандартных механизмах системы, которые могут выполнять действия по расписанию. Очень часто причиной "исчезновения" документов становится регламентное задание "Удаление помеченных объектов".
Поскольку Журнал регистрации "чист", нам потребуется создать собственный механизм логирования. Наиболее эффективным способом для этого будет использование расширения конфигурации.
ПередУдалением для всех документов и других объектов, удаление которых мы хотим отслеживать (например, справочники). Это событие срабатывает непосредственно перед тем, как система удалит объект.ПередУдалением мы реализуем запись детальной информации об удаляемом объекте в наш собственный регистр сведений или справочник. Такая информация может включать:
Документ.РеализацияТоваровУслуг).Ссылка).ПредставлениеОбъекта).Пользователи.ТекущийПользователь() или ИмяТекущегоПользователя()).ТекущаяДата()).ПолучитьЗначениеПараметра("ИмяКомпьютера"), если настроено).Для примера, создадим регистр сведений ЖурналУдаленияОбъектов с измерениями Пользователь (Справочник.Пользователи), ВидОбъекта (Строка), СсылкаОбъекта (Строка, для хранения UUID), ПредставлениеОбъекта (Строка) и ресурсом ДатаУдаления (Дата).
Пример кода для модуля подписки на событие:
// Подписка на событие "ПередУдалением" для всех документов
Процедура ПередУдалениемДокумента(Источник, Отказ, РежимУдаления) Экспорт
// Источник - это объект, который пытаются удалить
ЗаписатьВЖурналУдаления(Источник, Отказ, "Документ");
КонецПроцедуры
// Подписка на событие "ПередУдалением" для всех справочников
Процедура ПередУдалениемСправочника(Источник, Отказ, РежимУдаления) Экспорт
ЗаписатьВЖурналУдаления(Источник, Отказ, "Справочник");
КонецПроцедуры
// Вспомогательная процедура для записи в наш регистр
Процедура ЗаписатьВЖурналУдаления(Источник, Отказ, ТипОбъекта)
// Мы не блокируем удаление, а только фиксируем попытку/факт
// Если Отказ = Истина, то удаление не произойдет, но мы все равно можем это зафиксировать
Попытка
Запись = РегистрыСведений.ЖурналУдаленияОбъектов.СоздатьМенеджерЗаписи();
Запись.Пользователь = Пользователи.ТекущийПользователь();
Запись.ВидОбъекта = ТипОбъекта + "." + Источник.Метаданные().Имя;
Запись.СсылкаОбъекта = Строка(Источник.УникальныйИдентификатор());
Запись.ПредставлениеОбъекта = Строка(Источник);
Запись.ДатаУдаления = ТекущаяДата();
Запись.Записать();
Исключение
// Обработка исключений, если запись в наш журнал по какой-то причине не удалась
// Например, можно записать в служебный журнал или отправить уведомление
Сообщить("Ошибка при записи в журнал удаления: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Мы также можем усовершенствовать эту логику, чтобы фиксировать информацию о том, было ли удаление успешно (т.е., Отказ = Ложь).
Если Журнал регистрации чист, это может указывать на то, что злоумышленник имеет доступ к конфигуратору и может временно изменять код для отключения логирования или удаления документов напрямую, а затем возвращать изменения. Нам необходимо контролировать любой вход в конфигуратор.
ПриНачалеРаботыСистемы в общем модуле или модуле сеанса, если мы можем добавить такой код. Однако, если конфигурация на полной поддержке и на замке, то добавление кода напрямую в конфигурацию невозможно. В этом случае мы можем попробовать использовать расширение для подписки на событие ПриНачалеРаботыСистемы, но его функциональность в расширении может быть ограничена для такого рода событий. Альтернативно, если есть доступ к серверу 1С, можно настроить логирование активности на уровне операционной системы или СУБД для отслеживания запуска процессов 1С с флагом запуска конфигуратора.Пример (если есть возможность модифицировать модуль сеанса или общий модуль, который запускается при старте системы):
// В модуле сеанса или в общем модуле, который вызывается при старте
Процедура ПриНачалеРаботыСистемы()
Если Константы.РежимОтладки.Получить() Тогда // Пример условия для отладки
Возврат;
КонецЕсли;
// Проверяем, запущен ли режим конфигуратора
Если ОбщегоНазначения.ЭтоКонфигуратор() Тогда // Функция-обертка для проверки режима
ИмяТекущегоПользователя = Пользователи.ТекущийПользователь().Наименование;
Сообщение = "Пользователь '" + ИмяТекущегоПользователя + "' зашел в конфигуратор. Время: " + ТекущаяДата();
// Запись в служебный регистр сведений или журнал сообщений
// Можно также отправить по почте
ЗаписатьВЖурналСобытий("ВходВКонфигуратор", Сообщение);
// Отправка email (пример)
// ОтправитьПисьмоАдминистратору("Вход в конфигуратор", Сообщение);
КонецЕсли;
КонецПроцедуры
Примечание: функция ОбщегоНазначения.ЭтоКонфигуратор() не является стандартной. Её нужно реализовать самостоятельно или использовать НачатьПривилегированныйРежим() в связке с проверкой на наличие интерфейса конфигуратора, что сложнее и не всегда надежно. Более надежный способ – это отслеживать на уровне операционной системы или через службы сервера 1С.
Поскольку база опубликована, и пользователи работают через веб-клиент, мы должны тщательно проверить все опубликованные веб-сервисы и HTTP-сервисы (если они используются).
Версионирование объектов, если оно настроено, может быть полезным инструментом для отслеживания изменений и удалений, хотя оно не всегда напрямую указывает на пользователя, который инициировал программное удаление. Тем не менее, это позволяет восстановить состояние объекта до удаления и получить дополнительную информацию о его жизненном цикле.
Хотя резервное копирование не поможет выявить виновника, оно является обязательной мерой для минимизации потерь данных и может помочь сузить временной интервал, в котором произошло удаление.
Несмотря на то, что внешние обработки не добавлены в конфигурацию и пользователи работают через веб-клиент, существует гипотетическая возможность запуска внешних обработок с локального компьютера пользователя через COM-соединение или другие механизмы взаимодействия с клиентским приложением 1С.
Мы выясним, какие именно документы удаляются. Эта информация может дать нам важные подсказки о цели злоумышленника и, возможно, о используемом методе.
Удалить() без предварительной проверки ссылок.Применяя эти методы в комплексе, мы значительно повысим наши шансы на обнаружение пользователя, который осуществляет несанкционированное удаление документов. Главное — действовать системно, последовательно ограничивать потенциальные лазейки и собирать как можно больше информации о происходящих событиях.