После масштабного обновления конфигураций Зарплата и Управление Персоналом (ЗУП) и Зарплата и кадры государственного учреждения (ЗКГУ) до версии 3.1.38.18 (и некоторых смежных веток), пользователи и администраторы столкнулись с крайне опасным поведением системы. Проблема проявляется в виде ошибки Файл не обнаружен, но ее последствия могут быть гораздо серьезнее — вплоть до полной очистки диска C:\ на сервере 1С. В этой статье мы подробно разберем, почему это происходит, как найти уязвимый участок кода и какими способами можно устранить проблему.
Первоначальный анализ ситуации показал, что виновником является регламентное задание СинхронизацияДанных. При выполнении обмена данными система обращается к процедуре ВыполнитьОбменДаннымиЧерезФайловыйРесурс, которая расположена в общем модуле ОбменДаннымиСервер. Рассмотрим логику, добавленную разработчиками в последних релизах. Основная идея заключалась в том, чтобы автоматически очищать временные файлы сообщений обмена после их успешной загрузки, предотвращая «засорение» дискового пространства сервера.
Однако реализация этой логики содержит критическую уязвимость. Проанализируем участок кода, который вызывает сбой:
Если УдалитьСообщениеОбмена Тогда
ФайлСообщенияОбмена = Новый Файл(СообщениеОбмена);
Каталог = ФайлСообщенияОбмена.Путь;
УдалитьФайлы(Каталог);
КонецЕсли;
В этом фрагменте переменная СообщениеОбмена содержит путь к файлу выгрузки. Метод Путь объекта Файл извлекает путь к каталогу, в котором находится этот файл. Главная проблема заключается в том, что происходит при пустом или некорректном значении переменной СообщениеОбмена. В определенных условиях (например, если путь не задан в настройках синхронизации или возникла ошибка транспорта), метод Путь может вернуть корень текущего диска (например, C:\) или путь к временному каталогу профиля пользователя, под которым запущен rphost. Команда УдалитьФайлы(Каталог) выполняется рекурсивно и без дополнительных проверок, что приводит к попытке удаления всего содержимого указанного пути.
Разберем ситуацию, когда в настройках синхронизации указан несуществующий путь или обмен настроен через шину данных, где файловый ресурс не используется явно. Если алгоритм не получает четкого пути к файлу, объект Файл инициализируется некорректно. Рассмотрим пример цепочки событий:
УдалитьСообщениеОбмена устанавливается в значение Истина.УдалитьФайлы начинает обход всех папок на диске C:\.Посмотрим на реальный лог ошибки, который зафиксировали администраторы. Система пытается удалить даже те файлы, которые заняты другими процессами, что и вызывает исключение Ошибка совместного доступа к файлу. Это «спасает» часть данных, но те файлы, к которым у процесса 1С есть доступ на удаление, безвозвратно уничтожаются.
Особенно критична ситуация, когда служба 1C:Enterprise 8.3 Server Agent запущена от имени пользователя с правами локального администратора. В этом случае у 1С хватает полномочий на удаление системных файлов в Windows и Program Files. Мы можем увидеть это в журнале безопасности Security операционной системы через событие 4656 (аудит отказа), где процесс rphost.exe запрашивает дескриптор на удаление (DELETE) для критических библиотек .dll.
Для того чтобы убедиться, подвержена ли ваша база данной ошибке, проанализируем модуль ОбменДаннымиСервер. Нам нужно найти установку флага УдалитьСообщениеОбмена. В проблемных релизах код выглядит примерно так:
Если Транспорт.ПолучитьДанные Тогда
СообщениеОбмена = Транспорт.СообщениеОбмена;
РегистрыСведений.АрхивСообщенийОбменов.ПоместитьСообщениеВАрхив(
СтруктураНастроекОбмена.УзелИнформационнойБазы,
СообщениеОбмена);
УдалитьСообщениеОбмена = Истина;
Иначе
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
КонецЕсли;
Здесь видно, что после помещения сообщения в архив система помечает файл для удаления. Если переменная СообщениеОбмена не была должным образом проинициализирована транспортом, мы попадаем в зону риска.
Рассмотрим несколько способов исправления ситуации в зависимости от ваших возможностей по изменению конфигурации.
1. Установка официального патча (рекомендуется)
Фирма 1С оперативно выпустила исправления в виде расширений (патчей). Вам необходимо зайти в раздел Администрирование — Обслуживание — Обновление программы — Установленные исправления (патчи) и проверить наличие патча, исправляющего ошибку удаления файлов при обмене данными. Обычно это патчи серии EF_0016xxxx.
2. Обновление на исправленный релиз
Если ваша конфигурация находится на поддержке, необходимо обновиться до версий, где этот код либо закомментирован, либо обернут в проверку безопасности. Проанализируйте последние сборки в сервисе обновлений. В новых минорных релизах разработчики добавили проверку заполненности пути перед вызовом удаления.
3. Ручная правка кода (для программистов)
Если вы используете сильно измененную конфигурацию и не можете быстро обновиться, внесем изменения в общий модуль ОбменДаннымиСервер самостоятельно. Нам нужно добавить жесткую проверку на то, что удаляемый каталог не является корнем диска или пустой строкой. Рассмотрим пример безопасного кода:
Если УдалитьСообщениеОбмена Тогда
ФайлСообщенияОбмена = Новый Файл(СообщениеОбмена);
Каталог = ФайлСообщенияОбмена.Путь;
// Добавляем проверку на безопасность
Если ЗначениеЗаполнено(Каталог)
И Врег(Каталог) <> "C:\"
И Врег(Каталог) <> "\" Тогда
УдалитьФайлы(Каталог);
КонецЕсли;
КонецЕсли;
Эта проверка гарантирует, что если 1С не смогла определить конкретную папку обмена, она не начнет стирать данные с корня системного диска.
Разберем, как минимизировать ущерб от подобных ошибок в будущем на уровне инфраструктуры. Данный инцидент показал, насколько опасно запускать сервер 1С с избыточными правами.
Подводя итог, отметим, что ситуация с очисткой диска при синхронизации в ЗУП 3.1.38.18 является критической технической ошибкой платформенного уровня внутри конфигурации. Своевременный анализ кода модуля ОбменДаннымиСервер и установка исправлений позволят избежать катастрофической потери данных на сервере.