Безопасность сайта на WordPress редко становится темой разговора на этапе запуска: клиент хочет увидеть готовый дизайн и рабочую форму заявки, а не читать про файрволы. На практике я настраиваю базовую защиту сразу после сдачи проекта, потому что через 2-3 недели после публикации на сайт уже приходят боты, перебирающие пароли к wp-admin, и попытки залить шелл через уязвимый плагин. Ниже чек-лист того, что я делаю на каждом WordPress-проекте в первые дни после запуска.
Обновления ядра, плагинов и тем: первая линия защиты
Большинство взломов WordPress происходит не через изощрённые атаки, а через известные уязвимости в устаревших плагинах. Разработчики закрывают дыры в обновлениях, но если сайт стоит на версии плагина полугодовой давности, эта заплатка ему не помогает.
Я настраиваю на клиентских сайтах такой порядок:
- Автообновления для минорных версий ядра WordPress включены всегда, это правится в wp-config.php строкой define(‘WP_AUTO_UPDATE_CORE’, ‘minor’).
- Плагины и темы обновляю вручную раз в 1-2 недели, после проверки на тестовой копии сайта, чтобы обновление не сломало верстку или чекаут в WooCommerce.
- Неиспользуемые плагины и темы удаляю полностью, а не просто деактивирую. Деактивированный плагин с уязвимостью в коде всё равно лежит на сервере и может быть подключён напрямую.
Отдельно слежу за плагинами платежей и доставки: если на сайте стоит эквайринг T‑Bank через WooCommerce или модуль СДЭК для расчёта доставки, их обновления беру в приоритет, потому что в них хранятся ключи API и токены от внешних сервисов.
Защита админки и учётных записей
Админка WordPress по умолчанию доступна по адресу /wp-admin, и это первое, что проверяют боты-сканеры. Полностью прятать её не обязательно, но снизить количество автоматических попыток входа стоит.
Что я настраиваю на этом этапе:
- Меняю логин admin на нестандартный, если сайт мигрировал со старой установки или клиент делал её сам.
- Включаю двухфакторную аутентификацию для всех аккаунтов с ролью администратора, обычно через плагин Wordfence Login Security или Two Factor.
- Ограничиваю число попыток входа: после 5 неудачных попыток IP блокируется на 15-30 минут.
- Убираю лишние учётные записи с ролью администратора, которые остаются после разработки сайта подрядчиком или от старой команды.
Пароли для базы данных и FTP-доступа генерирую отдельно для каждого проекта и храню в менеджере паролей, а не в переписке с клиентом. Это касается и API-ключей: если в плагине настроена интеграция с СДЭК или сервисом рассылок, ключ прописываю в переменных окружения на сервере, а не в коде темы, чтобы он не утёк вместе с бэкапом или при случайной публикации репозитория.
Файрвол и защита от перебора паролей
Брутфорс-атаки на wp-login.php идут почти на любой сайт с посещаемостью выше нуля, боты не разбирают, интересен им конкретный сайт или нет, они сканируют диапазоны IP массово. Без файрвола на уровне приложения сервер тратит ресурсы на обработку каждого такого запроса, и при заметном трафике это ощутимо просаживает скорость.
Я использую связку из плагина безопасности (Wordfence или iThemes Security) и правил на уровне веб-сервера или CDN. Если сайт на хостинге с поддержкой Nginx, дополнительно закрываю прямой доступ к xmlrpc.php, если XML-RPC не используется, потому что через этот файл идёт значительная часть автоматизированных атак на подбор пароля.
При работе с интернет-магазинами на WooCommerce отдельно проверяю, что страницы оформления заказа и личного кабинета защищены от CSRF-атак теми же средствами, что идут в составе плагина эквайринга, потому что через уязвимости в форме заказа иногда пытаются подменить сумму платежа.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
SSL-сертификат и заголовки безопасности
HTTPS на сайте сейчас скорее гигиенический минимум, чем опция: без сертификата браузер помечает сайт как небезопасный, а поисковики понижают такие страницы в выдаче. Ставлю Let’s Encrypt через хостинг-панель или Cloudflare, обновление сертификата после этого идёт автоматически, вручную трогать не приходится.
Помимо самого сертификата настраиваю заголовки безопасности на уровне сервера:
- Strict-Transport-Security, чтобы браузер не пытался открыть сайт по HTTP даже по старой ссылке.
- X‑Content-Type-Options: nosniff, защищает от подмены типа контента в некоторых сценариях атак.
- X‑Frame-Options, запрещает встраивание сайта в чужой iframe, что закрывает часть clickjacking-атак на формы входа и оплаты.
Если на клиентском сайте параллельно работает лендинг на Tilda для рекламных кампаний, разница в подходе заметна сразу: на Tilda SSL и часть заголовков настроены на уровне платформы, разработчику остаётся только следить за собственными скриптами. На WordPress эта ответственность лежит на владельце хостинга и того, кто настраивал сайт.
| Задача безопасности | WordPress | Tilda |
|---|---|---|
| SSL-сертификат | настраивается вручную на хостинге | включается платформой автоматически |
| Обновления ядра | ответственность владельца сайта | отсутствует, платформа обновляется сама |
| Уязвимости в плагинах | основной источник взломов | риск переносится на кастомные скрипты и интеграции |
| Резервные копии | нужно настраивать отдельно | частично хранятся на стороне платформы |
Резервные копии и план восстановления после сбоя
Бэкап без проверки восстановления - это просто файл, который лежит на диске и создаёт иллюзию безопасности. Я настраиваю резервное копирование в трёх слоях: ежедневный бэкап базы данных, еженедельный полный бэкап файлов сайта и отдельное хранение копий вне основного сервера, обычно в другом облаке или на выделенном сервере под бэкапы.
Периодичность подбираю под тип сайта:
- Для интернет-магазина на WooCommerce с ежедневными заказами бэкап базы данных делаю каждые 6-12 часов, потому что откат на сутки назад означает потерю реальных заказов клиентов.
- Для сайта-визитки или блога без ежедневных изменений хватает ежедневного бэкапа с хранением за последние 14-30 дней.
Раз в 2-3 месяца разворачиваю резервную копию на тестовом сервере и проверяю, что сайт из бэкапа реально запускается. Без этой проверки легко обнаружить в момент реального сбоя, что архив битый или в нём не хватает части медиафайлов.
Плагины, темы и права доступа: где чаще всего дыры
Отдельно проверяю каждый плагин перед установкой на клиентский сайт: смотрю дату последнего обновления в каталоге WordPress.org, количество активных установок и открытые тикеты поддержки. Плагин, который не обновлялся больше года, ставлю только если для него нет живой альтернативы, и предупреждаю клиента, что он берёт на себя дополнительный риск.
Темы с нулированным кодом (взломанные премиум-темы, распространяемые бесплатно) на клиентских проектах не использую вообще: в них практически всегда зашит скрытый код, который открывает доступ на сервер third-party скриптам. Это правило действует и для плагинов из непроверенных источников.
Права доступа на файлы сервера настраиваю по стандартной схеме: 644 для файлов, 755 для директорий, wp-config.php закрываю до 440 там, где хостинг это позволяет. Учётным записям редакторов и авторов не даю доступ к установке плагинов и редактированию файлов темы через встроенный редактор кода в админке, эту возможность отключаю на уровне wp-config.php константой DISALLOW_FILE_EDIT.
Если проект сложнее типового блога, например, включает интеграцию с CRM или собственный API для мобильного приложения, настройку безопасности лучше закладывать на этапе архитектуры, а не патчить постфактум. В таких случаях я обычно беру разработку и настройку сайта на WordPress под ключ, чтобы защита была частью проекта с самого старта, а не отдельной задачей, которую вспоминают после инцидента.
Мониторинг и что делать, если сайт уже взломали
Даже с закрытыми базовыми дырами полностью исключить инцидент нельзя, поэтому настраиваю мониторинг: плагин безопасности присылает уведомление на почту при изменении файлов ядра или появлении новых учётных записей администратора. Отдельно проверяю логи веб-сервера раз в месяц на аномальные всплески запросов к wp-login.php или admin-ajax.php.
Если заражение всё же произошло, порядок действий такой:
- Перевожу сайт в режим обслуживания и меняю все пароли: от админки, FTP, базы данных и хостинг-панели.
- Сравниваю файлы сайта с чистой копией из репозитория или последнего чистого бэкапа, ищу изменённые или добавленные файлы.
- Восстанавливаю сайт из проверенного бэкапа, сделанного до заражения, а не пытаюсь вычистить вредоносный код построчно, это почти всегда дольше и менее надёжно.
- После восстановления обновляю все плагины и темы и только затем возвращаю сайт в рабочий режим.
Если своими силами разобраться со взломом не получается, для регулярной поддержки и мониторинга есть смысл держать сайт на техническом сопровождении, а не решать проблему заново с нуля при каждом инциденте.
Чтобы сайт работал без сбоев
Техподдержка
от 15 000 ₽/мес
Подробнее →Частые вопросы
Нужен ли отдельный плагин безопасности, если сайт на хорошем хостинге?
Хостинг обычно закрывает часть угроз на уровне сервера: файрвол сети, защиту от DDoS, изоляцию аккаунтов. Но уязвимости внутри самого WordPress, в конкретных плагинах и настройках админки хостинг не видит и не контролирует, для этого нужен отдельный плагин безопасности или ручная настройка на уровне приложения.
Сколько времени занимает базовая настройка безопасности после запуска сайта
На типовом сайте-визитке я закрываю весь чек-лист, обновления, двухфакторную аутентификацию, файрвол, SSL и бэкапы, за 3-4 часа. На интернет-магазине с эквайрингом и интеграциями время растёт до 1-2 рабочих дней, потому что добавляется проверка платёжных модулей и прав доступа к заказам.
Можно ли обойтись без платных плагинов безопасности
Базовый набор мер, обновления, сложные пароли, ограничение попыток входа, права доступа к файлам, закрывает большинство массовых атак и бесплатными инструментами. Платные версии плагинов добавляют более быстрое реагирование на новые уязвимости и расширенный мониторинг, что оправдано для магазинов и сайтов с высокой посещаемостью.
Что делать в первую очередь, если заметил на сайте подозрительный код или редирект
Сразу меняю все пароли и перевожу сайт в режим обслуживания, чтобы редирект не показывался посетителям. Дальше сравниваю файлы с чистой копией и восстанавливаю сайт из бэкапа, сделанного до появления проблемы, а не пытаюсь вручную вычищать заражённые файлы по одному.