Сначала составьте карту сайта, потом обновляйте
Инвентаризация CMS — это проверяемый список компонентов сайта, их версий, источников и ответственных. Он помогает понять, что именно затронуто обновлением или бюллетенем безопасности, и что нужно проверить перед изменениями. Покажу, как собрать такую карту для WordPress, Битрикса, OpenCart и Joomla.
Зачем инвентаризация, если можно просто нажать «Обновить всё»
Кнопка «Обновить всё» показывает только те компоненты, которые CMS и её механизм обновлений распознают. Архивный плагин, тема с сайта разработчика, собственный модуль, библиотека в vendor/ и версия PHP на хостинге требуют отдельной проверки. Уязвимость может быть и в ядре, и в расширении, и в самописном коде; заранее объявлять виноватым один слой — гадание. Поэтому перед обновлением я собираю список, а не нажимаю кнопку на удачу. Для оценки рисков сайта иногда нужен отдельный аудит безопасности CMS.
Когда появляется бюллетень об уязвимости, вопрос «этот компонент установлен?» должен решаться по карте, а не по памяти. Сверяем точное имя, источник, версию и условия уязвимости с первичным сообщением разработчика. Наличие похожего названия ещё не означает, что сайт затронут: важны ветка продукта, конфигурация и доступность уязвимого кода. Список сокращает поиск, но сам по себе не заменяет проверку бюллетеня и тестирование исправления.
Карта нужна и для совместимости. Обновление CMS может потребовать проверить PHP, тему, модули и собственные доработки. Я фиксирую зависимости, отмечаю, что тестировать первым, и сохраняю возможность вернуться к предыдущему состоянию. Это не обещает, что ничего не сломается; это даёт понятный план и снижает вероятность сюрприза в рабочее время. И да, «у нас сайт маленький» не превращает его код в бессмертный.
Что именно включать в карту компонентов
Минимальные поля моей карты: название и тип компонента, установленная версия, источник установки, статус, версия с доступным обновлением (если источник её предоставляет), ответственный, назначение и дата последней проверки. Для платной темы или модуля фиксирую ещё лицензию и способ получить обновление. Не смешивайте дату выпуска разработчиком с датой установки на сайте: это разные сведения. Владелец со стороны бизнеса помогает решить, нужен ли компонент; технический исполнитель отвечает за изменения.
В карту включаю не только CMS: PHP и его расширения, веб-сервер, СУБД, Composer-зависимости, задания планировщика и сторонние скрипты. Отдельно проверяю веб-каталог на старые копии, дампы, отладочные файлы и забытые загрузки. Их наличие не доказывает взлом, но доступные из интернета архивы могут раскрыть код или данные — доступность нужно проверить и закрыть. Для MySQL версию сервера можно получить запросом SELECT VERSION(); это полезная отдельная строка в карте, а не версия PHP из командной строки. В экспертной базе отдельно отмечено, что при разборе файловой системы полезно искать недавно изменённые файлы; неожиданные изменения требуют проверки, а не автоматического обвинения.
Неактивные расширения тоже заношу в список: статус «выключен» означает лишь, что компонент не включён обычным способом в CMS, а не то, что его код удалён с диска. Нельзя универсально утверждать, что любой неактивный плагин доступен напрямую по URL: это зависит от самого кода и настроек сервера. Если компонент больше не нужен, удаляю его после проверки зависимостей и резервной копии. Если оставляю — записываю зачем и кто отвечает. «На всякий случай» быстро превращается в музей файлов.
- Ядро CMS и установленные модули
- Активные и неактивные плагины, расширения и темы
- PHP, его расширения, веб-сервер и СУБД
- Composer-зависимости и сторонний код
- Копии, дампы, отладочные и временные файлы
- Версия, источник, назначение, владелец и дата проверки
Как быстро снять версии в WordPress, Битриксе, OpenCart и Joomla
Для WordPress использую WP-CLI: команды показывают установленные компоненты, статус, версию и доступное обновление, а формат CSV удобно сравнивать с прошлой выгрузкой. Запускайте инструмент с теми системными правами, которые приняты для обслуживания конкретного сайта; универсальное правило «только не root» без знания схемы доступа было бы слишком грубым. Пример для обычной установки:
wp core version
wp plugin list --fields=name,status,version,update,update_version --format=csv
wp theme list --fields=name,status,version,update,update_version --format=csv
php -vПараметр update_version — это предложенная версия обновления, если она известна WP-CLI. Пустое значение не доказывает, что компонент свежий: проверьте статус, источник и страницу разработчика. Установленные из стороннего источника расширения могут требовать отдельной сверки.
В Битриксе сверяю редакцию и установленные решения через штатные административные разделы обновлений и Marketplace, затем отдельно проверяю собственные доработки и сторонние модули. Для этого полезна отдельная проверка патч-уровня Битрикс. Имена меню могут различаться между версиями, поэтому ориентируюсь на установленный интерфейс и официальную документацию, а не на один универсальный путь к файлу. Версию PHP проверяю в окружении сайта; php -v в консоли показывает версию CLI, которая может отличаться от версии, используемой веб-сервером.
В OpenCart фиксирую версию магазина и перечень расширений через административную панель, а модификации проверяю отдельно: в отдельном разборе уязвимостей OpenCart я разбираю этот слой подробнее. Официальная документация OpenCart подтверждает, что OCMOD применяется и в ветке 4.x; файл модификации имеет расширение .ocmod.xml, а архив расширения может быть .ocmod.zip. В экспертной базе отдельно зафиксированы оба суффикса — мелочь, которая экономит время при проверке вручную. В Joomla сверяю версию ядра и расширения через административный интерфейс и документацию именно для установленной ветки. Затем сопоставляю список с файлами на диске: инвентаризация панели и инвентаризация файлов отвечают на разные вопросы. Файл в каталоге ещё не говорит, что он активен, а запись в панели не гарантирует, что каталог очищен после удаления.
- Сохранить исходный список и дату выгрузки
- Сверить версии с источником каждого расширения
- Отдельно проверить код вне панели управления
- Сопоставить версию PHP CLI с окружением сайта
- Записать неизвестные компоненты на ручную проверку
Заброшенные плагины и устаревшие версии: как их пометить
Я разделяю три состояния: обновление доступно; актуальная поддерживаемая версия установлена; статус поддержки неясен или компонент больше не сопровождается. Отсутствие свежего релиза само по себе ничего не доказывает: у проекта может быть редкий цикл выпуска или стабильная ветка. Проверяю страницу разработчика, журнал изменений, совместимость, ответы поддержки и доступность исправлений. Если источник молчит, записываю именно «статус не подтверждён», а не выдаю предположение за диагноз.
Срок без обновлений — сигнал для проверки, но не универсальный порог. Экосистемы и типы компонентов отличаются; фраза «год не обновлялся — удалить» слишком удобна, чтобы быть надёжным правилом. Для WordPress отдельно смотрю статус компонента в каталоге и сведения разработчика; для коммерческих расширений — действие лицензии и канал получения исправлений. В карте фиксирую дату, на которую проверил сведения, и ссылку на источник. Через месяц эта отметка уже может устареть.
Если исходный плагин изменяли вручную, сначала выясняю, какие файлы и строки отличаются от исходной версии. Обновление поверх таких изменений может затереть доработки, но оставить их без обновления тоже рискованно. Сохраняю копию, сравниваю с исходником, описываю назначение правок и выбираю путь: перенести изменение в поддерживаемый механизм, заменить компонент или оставить временно с ответственным и сроком пересмотра. Если diff большой, это повод для оценки объёма работ, а не автоматический приговор.
Владелец и критичность: без них список бесполезен
Список версий без владельцев — это красивая выгрузка, которую никто не будет поддерживать. Владелец компонента — человек со стороны бизнеса, который может ответить, зачем он нужен и можно ли его выключить на час. Это не обязательно технарь: для плагина рассылки владелец — маркетолог, для модуля оплаты — тот, кто отвечает за продажи, для формы обратной связи — менеджер, который разбирает заявки. Технический исполнитель — отдельная колонка. Если владельца нет ни у кого, это тоже ответ: значит, компонент кандидат на удаление в первую очередь.
Критичность — рабочая очередь, а не точная мера вероятности взлома. Я отмечаю, какие компоненты принимают данные, влияют на оплату, авторизацию или публикацию контента; затем смотрю, какие последствия даст отказ или компрометация. Срок реакции выбираю по конкретному бюллетеню, экспозиции и наличию исправления. Универсальное «высокая — сегодня, низкая — потом» не учитывает контекст, поэтому в записи указываю основание и дату следующего решения.
Отдельно отмечаю, можно ли удалить компонент и кто подтверждает его назначение. Сначала проверяю зависимости, активные сценарии и резервную копию; затем удаляю то, что не используется, и проверяю сайт. Удаление лишнего кода сокращает объём сопровождения, но не заменяет обновления оставшихся компонентов, контроля доступа и резервного копирования. Я не обещаю, что удаление пары модулей само по себе защитит сайт: это один понятный шаг в общей работе.
- Высокая: платежи, персональные данные, вход, анонимный ввод
- Средняя: функции сайта без доступа к данным клиентов
- Низкая: оформление, виджеты, вспомогательное
Как выглядит разбор карты без догадок
Вместо красивого кейса с цифрами, которые нельзя проверить, покажу рабочий разбор. Допустим, владелец сайта считает, что расширений немного. Я снимаю список из CMS, отдельно обхожу каталоги и сравниваю результаты. Несовпадения раскладываю по типам: неучтённое расширение, старая копия, собственная доработка, временный файл. На этом этапе ничего не удаляю: сначала выясняю назначение и проверяю, не используется ли код сайтом.
Для каждой найденной записи оставляю след: путь или идентификатор, версия, источник, дата проверки и ответственный. Если версия не определяется автоматически, так и пишу — «не установлена, проверить вручную». Если поддержка неизвестна, прикладываю страницу разработчика и дату просмотра. Так в списке нет ложной точности, а коллега может повторить проверку. Подозрительный файл отправляется на отдельный анализ; одно только необычное имя не доказывает наличие вредоносного кода.
После сверки я обсуждаю с владельцами функций, что можно удалить, а что требует тестовой копии. Затем формирую небольшой план: сначала закрыть публично доступные забытые копии и известные исправляемые проблемы, потом проверить совместимость и обновить компоненты в согласованном порядке. Для каждого изменения записываю проверку после релиза и способ отката. Подготовку копии и возврат к ней поясняет инструкция по откату взломанного WordPress. На выходе получается не отчёт ради отчёта, а список решений с владельцами и следующими действиями.
- Сверить админку с файлами на диске
- Пометить неустановленные версии как неизвестные
- Подтвердить назначение с владельцем функции
- Согласовать тест, обновление и откат
Как поддерживать карту живой и что делать дальше
Разовая инвентаризация устаревает после установки или удаления компонентов. Частоту автоматической выгрузки выбираю по скорости изменений сайта и доступным инструментам; для небольшого проекта можно начать с выгрузки перед каждым плановым окном обновлений и после изменений. Если сайт меняется часто, автоматизируйте сбор. Сравнивайте не только число строк, но и конкретные добавления, удаления, смену версий и статусов. Разница без ответственного — ещё один файл, который никто не читает.
Новое расширение добавляю в карту вместе с источником, назначением, версией и ответственным. Храню журнал изменений рядом с документацией сопровождения, с доступом у владельца бизнеса и технического исполнителя. Сведения о лицензиях держу отдельно с ограниченным доступом: секреты и ключи не должны попадать в общую таблицу. После обновления проверяю критические функции сайта и записываю результат, а не ставлю галочку по факту нажатия кнопки.
Эта карта помогает решать, какие обновления проверять и какие уведомления относятся к вашему сайту. Для оценки уязвимостей нужны точная версия, условия эксплуатации и бюллетень первичного источника; слово «уязвимость» само по себе ещё не означает, что сайт можно взломать в один клик. Начните с полного списка, затем закройте конкретные пробелы. Идеальная таблица не нужна — нужна та, по которой действительно принимают решения.
Частые вопросы
Достаточно ли списка плагинов из админки CMS?
Нет. Сверьте его с файлами сайта и собственными доработками: панель и файловая система показывают разные части картины.
Опасен ли выключенный плагин?
Его код остаётся установленным, пока вы его не удалили. Риск прямого доступа зависит от кода и настроек, поэтому ненужное расширение лучше удалить после проверки зависимостей.
Как часто обновлять карту?
Собирайте её после изменений и перед плановыми обновлениями. Автоматическую периодичность выбирайте по частоте изменений сайта.
Как найти версию Битрикса без догадок?
Сверьте сведения в штатных административных разделах обновлений и Marketplace с официальной документацией для установленной версии. Единственный путь к файлу может отличаться.
Кто должен быть владельцем компонента?
Сотрудник, который понимает его назначение и согласует отключение или замену. Технический исполнитель указывается отдельно.
Источники
- WP-CLI: wp plugin list — Поддерживаемые поля, статусы и форматы вывода списка плагинов: https://developer.wordpress.org/cli/commands/plugin/list/
- WP-CLI: wp theme list — Поля статуса и версии темы, CSV-формат: https://developer.wordpress.org/cli/commands/theme/list/
- 1С-Битрикс: документация — Официальная документация платформы и штатных средств управления: https://dev.1c-bitrix.ru/
- Joomla Programmers Documentation: Manifest Files — Официальные сведения о манифестах расширений; конкретные пути сверяйте с веткой Joomla: https://manual.joomla.org/docs/next/building-extensions/install-update/installation/manifest/
- OpenCart: Extensions — Типы расширений и применение OCMOD в OpenCart 4.x: https://docs.opencart.com/developer-guide/extensions
- MySQL 8.4 Reference Manual: VERSION() — Функция VERSION() возвращает версию MySQL Server: https://dev.mysql.com/doc/refman/8.4/en/information-functions.html



