Свежий main, старый fileman: как проверить реальный patch level Битрикс
В админке зелёный статус, обновление прошло, заявку закрыли. А на втором веб-сервере осталась старая копия партнёрского модуля. Я, Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш», считаю обновление принятым только после проверки конкретных модулей и исполняемого кода. Покажу, как собрать такую проверку: от main и fileman до решений Маркетплейса, локальных копий компонентов и PHP-процессов.
1. Что на самом деле означает версия продукта
Начну с важного уточнения: номер продукта внизу административной панели Битрикс означает версию главного модуля main. Это не отдельный счётчик, который подтверждает состояние всей установки. Поэтому нормальный сценарий нашей задачи выглядит так: main обновлён, а fileman или партнёрский модуль отстаёт. Если свежий номер в админке противоречит версии main на диске, сначала проверяйте узел, DOCUMENT_ROOT и источник показанного номера. [Пояснение разработчика](https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=57&LESSON_ID=23444&LESSON_PATH=5442.23446.23444).
Система обновлений работает с версиями отдельных модулей и учитывает зависимости. В ней можно выбирать обновления, а в экспертном режиме — ограничивать установку определённой версией. Поэтому фраза «мы обновляли Битрикс в пятницу» для меня почти бесполезна. Нужен перечень: какие модули, до каких версий, на каких серверах и с каким результатом. Журнал установки помогает восстановить эту картину. [Документация SiteUpdate](https://dev.1c-bitrix.ru/user_help/marketplace/sysupdate.php).
С Маркетплейсом добавляется отдельная цепочка: разработчик решения, его выпуск, доступность обновления для вашей установки и фактическая доставка файлов. Я отдельно открываю обновления решений и проверяю условия получения новых версий. Статус «обновлений нет» имеет смысл только после успешного обращения к серверу обновлений. Ошибка соединения, ограничение доступности или давно не запускавшаяся проверка не превращают установленный код в исправленный.
Мой рабочий patch level — это запись из четырёх частей: обнаруженная версия, применимый бюллетень, подтверждение установки исправления и проверка работающего экземпляра. У каждой записи есть дата и конкретный узел. Единственного числа «сайт безопасен на версии X» я в отчёт не ставлю. Оно слишком легко скрывает старую библиотеку, забытый обработчик или второй сервер, на который обновление вообще не попало.
2. Собираю два списка: зарегистрированные модули и файлы
Первый список беру в разделе «Настройки → Настройки продукта → Модули»: идентификатор, версия, установлен ли модуль. Для автоматизации в доверенном окружении есть ModuleManager::getInstalledModules(), getVersion() и getModulesFromDisk(). Но реестр установленных модулей не отвечает на вопрос, какие файлы физически остались на сервере. Неустановленный модуль тоже может лежать на диске; его доступность и возможность выполнения нужно разбирать отдельно. [Страница модулей](https://dev.1c-bitrix.ru/user_help/settings/settings/module_admin.php), [API ModuleManager](https://docs.1c-bitrix.ru/api/classes/Bitrix-Main-ModuleManager.html).
Второй список собираю непосредственно из /bitrix/modules и /local/modules. Оба дерева обязательны: при поиске соответствующих файлов Битрикс отдаёт приоритет /local. Две директории с одинаковым ID нельзя молча объединять в одну строку отчёта. Сохраняйте логический и физический путь, особенно при симлинках и переключении релизов. Сначала установите, какой каталог обслуживает нужный виртуальный хост, затем запускайте инвентаризацию. [Структура директорий](https://docs.1c-bitrix.ru/pages/get-started/directory-structure.html).
Для первого прохода я выбираю чтение файлов без запуска PHP. Следующий скрипт сохраняйте вне DOCUMENT_ROOT как inventory.py. Он требует Python 3, читает стандартную декларацию VERSION и выводит отдельную JSON-строку для каждого каталога модуля. Пример запуска: python3 /srv/audit/inventory.py /srv/www/shop. При сохранении вывода файл отчёта тоже размещайте вне веб-корня. ```python import json, re, sys from pathlib import Path if len(sys.argv) != 2: sys.exit("Usage: inventory.py DOCUMENT_ROOT") root = Path(sys.argv[1]).resolve(strict=True) if not (root / "bitrix/modules").is_dir(): sys.exit("DOCUMENT_ROOT/bitrix/modules is not a directory") pattern = re.compile(rb'''['"]VERSION['"]\s*=>\s*['"](\d+\.\d+\.\d+)['"]''') for relative in ("bitrix/modules", "local/modules"): base = root / relative if not base.is_dir(): continue for module in sorted(base.iterdir()): if not module.is_dir(): continue file = module / "install/version.php" row = {"module": module.name, "path": str(file), "physical_path": str(file.resolve()), "version": None, "status": "review"} try: matches = pattern.findall(file.read_bytes()) if len(matches) == 1: row.update(version=matches[0].decode("ascii"), status="literal_found") else: row["reason"] = "missing_or_multiple_VERSION" except OSError as error: row["reason"] = type(error).__name__ print(json.dumps(row, ensure_ascii=False)) ```
Это намеренно ограниченный инструмент. Он не интерпретирует PHP и может найти VERSION внутри комментария; вычисляемую версию он не распознает. Статус literal_found означает только найденную декларацию. Строки review разбирайте вручную. Скрипт не определяет регистрацию модуля, выбранный загрузчиком код или завершение миграций. Запускайте его на каждом отдельном дереве приложения, включая узлы фоновых заданий. При подозрении на взлом предпочтительна проверка сохранённой копии файлов из доверенного окружения.
3. Сопоставляю версии с конкретными бюллетенями
После инвентаризации открываю два источника: центр обновлений безопасности самого Битрикс и реестр уязвимых сторонних решений. Затем перехожу в карточки разработчиков и исследователей. Приведённые ниже сведения проверены на 5 сентября 2026 года. Таблица показывает несколько важных контрольных точек; полный перечень применимых уязвимостей нужно собирать по составу вашего сайта. [Бюллетени платформы](https://www.1c-bitrix.ru/vul/), [реестр сторонних решений](https://www.1c-bitrix.ru/vul_dev/).
В рабочей таблице я обязательно связываю номер исправления с идентификатором ошибки. Иначе через год старый порог начинают использовать как универсальное разрешение ничего больше не обновлять. | Компонент | Конкретная проблема | Версия исправления | | --- | --- | --- | | main | BDU:2025-08663, превышение привилегий при работе с почтовыми шаблонами | [25.100.400](https://www.1c-bitrix.ru/vul/25346794/) | | fileman | BDU:2025-08662, превышение привилегий при копировании файлов | [24.500.100](https://www.1c-bitrix.ru/vul/25346784/) | | iblock | BDU:2025-08665, чтение файлов при XML-импорте | [24.300.100](https://www.1c-bitrix.ru/vul/25346820/) | | main | BDU:2026-04276, раскрытие настроек почтовых отправлений | [26.150.100](https://www.1c-bitrix.ru/vul/28287820/) | | landing | BDU:2026-05965, включение локальных файлов при редактировании лендинга | [25.1100.100](https://www.1c-bitrix.ru/vul/27618322/) | | esol.importexportexcel | Исправления безопасности из бюллетеня 27.12.2025 | [3.2.6](https://esolutions.su/bezopastnost-saytov/dorabotki-bezopasnosti-moduley-importa/) |
Здесь легко преувеличить риск. Исследователи Positive Technologies указывают, что рассматриваемые ошибки 2025 года в main, fileman и iblock требовали авторизованного доступа; для iblock — прав управления инфоблоками. Это существенное условие, которое нельзя выбрасывать из отчёта. Чтение файла, включение локального файла и RCE тоже не синонимы: возможность исполнения кода зависит от конкретной ошибки и условий. Однако украденная учётка редактора делает такие ограничения вполне практической проблемой. [Разбор исследователей](https://ptsecurity.com/about/news/pt-experts-helped-to-strengthen-security-in-1c-bitrix-systems/).
Показательный пример — esol.importexportexcel. Порог 2.9.0 относится к старой проблеме; декабрьский бюллетень 2025 года уже указывает исправление 3.2.6. Проверка только старой известной RCE оставит новые вопросы без ответа. Разработчик отдельно уточняет, что для описанных декабрьских ошибок нужны доступ в административную часть и права работы с модулем. Я фиксирую и версию, и условия, и дату бюллетеня. Если поставщик не опубликовал полный диапазон затронутых версий, не придумываю его самостоятельно. [Бюллетень разработчика](https://esolutions.su/bezopastnost-saytov/dorabotki-bezopasnosti-moduley-importa/).
4. Учебный разбор: два узла условного «Вектора»
Для воспроизводимого разбора беру файловую модель ООО «Вектор»: условная производственная компания на 120 рабочих мест, B2B-каталог, два веб-узла. Это учебный сценарий с синтетическими файлами версий; реальная CMS здесь не разворачивалась. Архитектурная вводная — отдельные деревья кода web01 и web02 за балансировщиком. Именно такая схема требует проверки каждого узла: общая база данных сама по себе не синхронизирует содержимое дисков.
В обоих деревьях задаю main 26.150.100, fileman 24.500.0 и esol.importexportexcel 3.2.0. На web02 дополнительно оставляю копию партнёрского модуля версии 2.9.0 в /local/modules. Первый запуск приведённого скрипта действительно дал три записи для web01 и четыре для web02. Дубликат сохранился отдельной строкой, как и требовалось. | Путь относительно корня сайта | web01 | web02 | | --- | --- | --- | | bitrix/modules/main | 26.150.100 | 26.150.100 | | bitrix/modules/fileman | 24.500.0 | 24.500.0 | | bitrix/modules/esol.importexportexcel | 3.2.0 | 3.2.0 | | local/modules/esol.importexportexcel | отсутствует | 2.9.0 |
Получились три задачи: проверить отставание fileman от нужного исправления, обновление партнёрского решения и происхождение его локальной копии. Для второго файлового прогона меняю декларации fileman на 26.0.0, партнёрского модуля — на 3.2.6, а дубликат переношу за корень модели. Результат: по три записи, ноль дублирующих ID и ноль расхождений версий между узлами. Версия fileman 26.0.0 действительно опубликована в истории модуля, но здесь использована только как значение учебной проверки. [История fileman](https://dev.1c-bitrix.ru/docs/versions.php?lang=ru&module=fileman).
На настоящем проекте простое изменение VERSION ничего не исправляет. Перед переносом локального модуля нужно выяснить, какие доработки и зависимости он содержит; затем установить официальные обновления и проверить фактические файлы. Итог эксперимента скромный, но полезный: инвентаризация обнаруживает копию, которую потерял бы отчёт с одной строкой на ID. Дополнительно проверены отсутствующий version.php, несколько деклараций VERSION и симлинки. Работоспособность магазина и закрытие уязвимостей этим тестом не подтверждались — для них нужна следующая часть приёмки.
5. Как доказать, что исправление действительно работает
Сначала разбираю завершение установки: ошибки копирования, права на каталоги, свободное место, выполнение обновляющих скриптов. Битрикс допускает updater.php, который меняет не только файлы внутри модуля, но и внешние файлы или базу данных. Поэтому свежий install/version.php не доказывает успешное прохождение всей процедуры. Особенно внимательно проверяйте установки, где обновление прерывали, повторяли вручную или восстанавливали только часть файлов из резервной копии. [Механизм обновления модулей](https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=101&LESSON_ID=3218).
Дальше проверяю именно файлы, затронутые исправлением, и рабочие копии компонентов. Источником сравнения служит доверенный пакет соответствующей версии, официальный патч или чистая контрольная установка, обновлённая тем же способом. Проверяю /local/components, /bitrix/components, PHP в шаблонах и самостоятельные обработчики, связанные с решением. Совпадение хешей двух серверов доказывает одинаковость файлов, но оба сервера могут содержать одинаковую старую копию. Для подтверждения исправления нужен доверенный эталон.
Третий слой — работающие PHP-процессы. Например, конфигурация ниже требует явного применения изменений к OPcache; сама замена файлов недостаточна. Я включаю в процедуру управляемый перезапуск обслуживающего сайт PHP-FPM на каждом узле, с выводом узла из балансировки и проверкой после возврата. Это пример настройки, а не рекомендация включать её на любом сайте. При использовании дискового кеша OPcache его состояние тоже нужно учитывать. [Настройки OPcache](https://www.php.net/manual/en/opcache.configuration.php). ```ini opcache.enable=1 opcache.validate_timestamps=0 opcache.file_cache="" ```
Последний слой — проверка поведения. На изолированной копии использую безопасный контрольный сценарий для конкретного исправления: тестовую учётку с нужными ограничениями и специально подготовленные несекретные данные. Параллельно проверяю обычные операции: редактор, импорт, обмен, оформление заказа. Один ответ 403 через WAF ничего не доказывает о коде на backend. Если обнаружены признаки прежнего взлома, обновление сопровождается расследованием: сохранением артефактов, проверкой постороннего кода и учёток, а при подтверждённой утечке — заменой секретов.
6. Что делать первым и как не повторять проверку с нуля
Я начинаю с доступных извне компонентов и известных применимых ошибок с тяжёлыми последствиями. Если исправление пока невозможно установить, временно ограничиваю доступ к затронутой функции и назначаю срок устранения. Ограничение админки через VPN полезно, но сначала нужно проверить, действительно ли опасный маршрут находится только там. У модулей бывают отдельные обработчики и другие точки входа. Отключение пункта меню не означает отключение серверного кода.
Обычные обновления сначала прогоняю на копии с проверяемым восстановлением файлов и базы. Состав тестов определяется бизнесом: для каталога с импортом важнее корректный обмен и обработка ошибок, чем идеальная проверка каждой административной кнопки. На копии отключаю реальные платежи, рассылки и внешние задания. Если обновляющий скрипт меняет схему данных, возврат старого каталога приложения сам по себе может оказаться неполным откатом.
После приёмки сохраняю реестр: узел, DOCUMENT_ROOT, ID и путь модуля, версия, бюллетень, подтверждение исправления, дата проверки и ответственный. Для перенесённого исправления без изменения версии дополнительно нужны происхождение патча и проверенные файлы. Такой случай допустим, но сопровождать его дороже: следующий администратор должен понимать, почему установлен старый номер и на каком основании конкретная ошибка считается закрытой.
Ежедневно можно сравнивать текущую инвентаризацию с принятой и сообщать о новых модулях, дублях, откатах версий и необъяснимых изменениях кода. Бюллетени проверяйте отдельно: отсутствие изменений на сервере не означает отсутствия новых сведений об уязвимостях. Я спокойно откладываю косметические обновления интерфейса и охоту за красивым номером. Откладывать разбор старого исполняемого модуля, который доступен пользователям и никем не сопровождается, значительно дороже.
- Сначала: применимые критичные уязвимости, доступные точки входа и признаки уже произошедшего взлома.
- Затем: официальное исправление, проверка файлов и миграций, обновление PHP-процессов, функциональная приёмка.
- Следом: забытые решения, локальные копии, неподдерживаемые доработки и расхождения между узлами.
- Постоянно: контроль состава приложения и новых бюллетеней с назначенным ответственным.
Частые вопросы
Можно проверить patch level только из браузера?
В админке можно собрать исходный список версий. Для подтверждения состояния файлов на каждом узле, локальных копий и PHP-процессов нужен доступ к инфраструктуре либо соответствующие проверяемые отчёты.
Старый номер версии всегда означает незакрытую уязвимость?
Нет. Возможно отдельное официальное исправление без смены номера. Но его наличие нужно подтвердить происхождением патча и состоянием затронутых файлов; устного заявления недостаточно.
Свежая версия модуля исключает старый уязвимый код?
Нет. Могли остаться копии компонентов, незавершённое обновление, другое дерево на соседнем узле или старый код в OPcache. Версия — отправная точка проверки.
Можно удалить неиспользуемый модуль?
После проверки зависимостей, обработчиков, агентов, заданий и нужных данных. Затем нужно убедиться, что не остались доступные исполняемые файлы. Простое удаление каталога может нарушить работу сайта.
Я помогу проверить patch level вашего Битрикс: собрать модули и локальные копии, сопоставить их с бюллетенями и подготовить проверяемый план обновления. Обратитесь в [«АйТи-Фреш»](https://itfresh.ru/) — разберём оставшиеся риски и организуем приёмку исправлений.
Бесплатная консультация →

