Ревью WordPress-плагина: практический чек-лист
Плагин может работать на тестовом сайте и при этом ломать обновления, открывать служебные данные или замедлять админку. Чек-лист помогает проверить код по четырём направлениям до релиза.

Что проверять в плагине до релиза
Плагин для WordPress 6.x может не выдавать ошибок на тестовом сайте, но всё равно содержать SQL-инъекцию, незакрытый REST-эндпоинт или запросы к базе на каждой загрузке страницы. Хорошее ревью ищет не только явные баги: оно проверяет границы доступа, жизненный цикл хуков, совместимость с обновлениями и цену работы кода на проде.
Ниже — чек-лист для ревью собственного или стороннего плагина. Он рассчитан на PHP-код, административные страницы, AJAX или REST API, работу с базой и подключение ассетов. Примеры ориентированы на WordPress 6.x; минимальную версию WordPress и PHP нужно сверять с заявленными требованиями конкретного проекта.
Главный вопрос ревью: что произойдёт, если этот код вызовет не администратор, передаст неожиданные данные или откроет страницу в десять раз чаще обычного.
Четыре прохода вместо одного чтения файла
Читать плагин сверху вниз обычно неэффективно. Сначала определите точки входа, затем проведите несколько коротких проходов с разными вопросами. Так легче заметить ошибки, которые теряются в общем потоке кода.
| Проход | Что проверяет | Цена и результат |
|---|---|---|
| Быстрый | Точки входа, права, внешние запросы, работа с базой | Подходит для небольшого патча; быстро находит критические риски, но не заменяет полный разбор |
| Безопасность | Аутентификация, авторизация, nonce, экранирование, SQL и загрузки файлов | Занимает больше времени; снижает риск уязвимостей, но не проверяет архитектуру |
| Совместимость | Хуки, версии WordPress и PHP, конфликты имён, активация и удаление | Нужен перед публикацией или обновлением; выявляет поломки чужой установки |
| Производительность | Запросы к базе, внешние HTTP-вызовы, cron, ассеты и кэш | Требует профилирования и стенда; показывает, что станет дорогим при росте трафика |
Точка входа — место, через которое пользователь, запрос, cron-задача или сам WordPress запускает код: обработчик хука, REST-маршрут, AJAX-действие, shortcode или страницу админки.
Чек-лист ревью
1. Карта плагина и жизненный цикл
До анализа отдельных функций найдите главный файл с заголовком плагина, регистрацию хуков, обработчики активации и деактивации, cron-события, REST-маршруты и страницы админки. Зафиксируйте минимальные версии WordPress и PHP. Если они нигде не указаны, это уже замечание: поддержку нельзя проверять без контракта.
- Есть ли префикс у функций, классов, констант, хуков и ключей мета-данных. Общие имена вроде
init,settingsилиdataповышают риск конфликта. - Не выполняется ли тяжёлая логика прямо при подключении файла. Регистрация хуков должна быть отделена от операций, которые требуют запроса к базе или внешнего сервиса.
- Создаются ли таблицы, опции и cron-задачи только при активации, а не при каждом запросе.
- Удаляются ли созданные данные при деактивации или полном удалении, если это предусмотрено настройками. Нельзя молча удалять пользовательские данные без понятного выбора.
- Можно ли безопасно повторно активировать плагин и выполнить обновление с предыдущей версии.
Формулировка замечания: «Регистрация cron-задачи находится в обычном загрузочном пути. При каждом запросе проверяется и создаётся одно и то же событие. Перенесите планирование в активацию или добавьте идемпотентную проверку с понятным обновлением расписания».
2. Доступ и границы полномочий
Проверяйте не только наличие nonce. Nonce подтверждает происхождение запроса, но не заменяет проверку прав пользователя. Для каждой административной формы, AJAX-операции и REST-точки задайте вопрос: кто может вызвать действие и что произойдёт при вызове без нужной роли.
- Для изменения настроек и данных есть проверка capability через
current_user_can()или эквивалентную проверку, соответствующую операции. - Для форм и AJAX проверяется nonce, а отказ возвращает безопасный ответ без продолжения операции.
- У REST-маршрутов задана проверка разрешений через
permission_callback. Нельзя считать сам факт авторизации достаточным доступом к каждой операции. - Идентификатор записи, пользователя или заказа не считается доказательством права доступа. После его получения проверяется принадлежность объекта текущему пользователю или наличие нужной capability.
- Скрытие кнопки в интерфейсе не используется как единственная защита: прямой запрос должен получать отказ.
Ищите цепочку целиком: входные данные → проверка пользователя → проверка права → изменение объекта → ответ. Если один этап отсутствует, замечание должно указывать конкретный путь, например «POST на административный обработчик меняет опцию до проверки capability».
3. Входные данные, вывод и база
Разделяйте три операции: проверку значения, очистку и экранирование. Очистка входа не делает строку безопасной для любого контекста, а экранирование должно происходить там, где значение выводится: в HTML, атрибуте, URL или JavaScript-контексте.
- Для числовых идентификаторов проверяется тип и допустимый диапазон, а не только наличие параметра.
- Значения из формы, URL, REST-запроса и пользовательских мета-полей не попадают в HTML без контекстного экранирования, например через
esc_html(),esc_attr()или подходящий инструмент для URL. - SQL-запросы с переменными используют подготовку через
$wpdb->prepare(). Склейка строки с идентификатором, сортировкой или фильтром требует отдельной проверки допустимых значений. - При сохранении настроек проверяется схема данных: допустимые ключи, типы, длина строк и значения по умолчанию. Нельзя бездумно сохранять весь массив из запроса.
- Импорт и загрузка файлов ограничивают размер, расширения, MIME-тип, место хранения и права доступа. Имя файла от пользователя не должно напрямую становиться путём.
Отдельно проверьте вывод в админке и на публичной странице. XSS часто появляется не в момент сохранения, а позже — когда значение выводится в другом контексте.
4. Хуки, настройки и совместимость
У каждого хука есть контракт: момент вызова, аргументы и ожидаемый тип возвращаемого значения. Ошибка здесь может не проявиться на странице плагина, но сломать другой код после обновления WordPress.
- Количество аргументов в
add_action()иadd_filter()соответствует фактическому callback. - Фильтр возвращает значение, а action не меняет поток выполнения неожиданным
exitилиdie, если это не предусмотрено сценарием. - Плагин не переопределяет глобальные переменные, стандартные классы и функции WordPress.
- Подключение CSS и JavaScript ограничено нужными страницами, а зависимости и версии ассетов объявлены явно.
- Переводимые строки используют систему локализации WordPress и не получают пользовательский ввод как имя домена перевода.
- Код не полагается на наличие конкретной темы, конструктора или другого плагина без проверки зависимости и понятного сообщения об ошибке.
Замечание должно быть проверяемым: не «плохая совместимость», а «скрипт подключается на всех страницах сайта, хотя используется только в настройках плагина; это добавляет запросы к каждому публичному ответу и может конфликтовать с глобальным обработчиком».
5. Производительность и внешние зависимости
Измеряйте не абстрактную «скорость плагина», а число запросов к базе, время внешних HTTP-вызовов, размер ассетов и частоту выполнения обработчиков. Без замеров не называйте код медленным как установленный факт.
- Нет ли запроса к базе внутри цикла, который проходит по постам, товарам или пользователям.
- Не вызывается ли внешний API на каждом просмотре страницы без кэша, тайм-аута и обработки отказа.
- Не запускается ли тяжёлая синхронизация в обычном веб-запросе вместо фоновой задачи или очереди.
- Не увеличивает ли плагин число автозагружаемых опций без необходимости. Размер таких данных стоит проверить на тестовой копии базы.
- Есть ли пагинация, ограничения размера выборки и защита от повторного запуска долгой операции.
- Что увидит пользователь при тайм-ауте внешнего сервиса: ошибку, пустой результат или бесконечное ожидание.
Для проверки используйте staging-копию, журнал запросов и профилировщик, совместимые с вашей версией PHP и WordPress. Сравнивайте одинаковый сценарий: одна и та же страница, база, кэш и число повторов. Числа «до» и «после» без этих условий мало что значат.
Что ломается чаще всего
Ниже — пять типичных замечаний, которые стоит искать целенаправленно:
- Nonce принят за авторизацию. Запрос защищён токеном, но любой пользователь с подходящим nonce может вызвать действие. Нужна отдельная проверка capability.
- REST-маршрут открыт по умолчанию. Обработчик возвращает данные, а проверка разрешений отсутствует или всегда разрешает запрос.
- Экранирование выполнено не в том контексте. Значение очищено при сохранении, но вставлено в HTML-атрибут или JavaScript без подходящего экранирования.
- SQL безопасен только для одного параметра. Идентификатор подготовлен, но сортировка, имя поля или дополнительный фильтр склеиваются в запрос напрямую.
- Тяжёлая задача спрятана в хуке страницы. Синхронизация запускается при открытии админки и делает внешний запрос для каждого оператора.
Каждое замечание оформляйте по схеме: место в коде, сценарий воспроизведения, риск, исправление и уровень серьёзности. Например: «Критично — REST-операция меняет настройки без проверки права. Отправка запроса от авторизованного пользователя приводит к изменению глобальной опции. Добавить проверку capability до записи и тест на пользователя без нужного права».
Когда быстрый чек-лист недостаточен
Быстрого прохода достаточно для маленького изменения, которое не добавляет новые точки входа и не работает с чувствительными данными. Полный разбор нужен, если плагин принимает платежи, загружает файлы, обрабатывает персональные данные, создаёт публичные REST-маршруты, меняет права пользователей или выполняет массовую синхронизацию.
Отдельная тема — инвалидация кэша: здесь важно лишь проверить, не отдаёт ли плагин устаревшие данные после изменения настроек. Стратегию кэширования стоит ревьюить отдельно.
Что делать дальше
Сохраните чек-лист в шаблоне pull request и требуйте от автора указать затронутые точки входа, права доступа, изменения схемы данных и условия отката. После ревью проверьте плагин на staging-копии WordPress 6.x с минимально заявленными версиями PHP и WordPress, а затем поставьте наблюдение за ошибками PHP, неудачными внешними запросами, временем административных страниц и количеством запросов к базе.
Первый практический шаг — написать тесты на три сценария: пользователь без нужного права, неожиданный ввод и отказ внешнего сервиса. Если плагин переживает их предсказуемо, дальнейшее ревью становится проверкой конкретных рисков, а не чтением кода без измеримого результата.
Тендерный специалист 44-ФЗ / 223-ФЗ: Разбор PDF-документации закупки, поиск «заточек» под поставщика, чек-лист заявки.
Спросить за 20 ₽Источники: WordPress Plugin Handbook, WordPress Plugin Security
Частые вопросы
Нужно ли проверять nonce, если действие доступно только администратору?
Можно ли считать плагин безопасным, если в нём нет SQL-запросов?
Что проверять, если плагин должен работать на нескольких версиях WordPress?
Как понять, что замечание действительно связано с производительностью?
Что делать, если после установки плагина сайт начал отдавать белый экран?
Нужен ли отдельный ревью для кода, который запускается только из админки?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.