WordPress: как защитить сайт от взлома
Три года назад я потерял сайт с посещаемостью 8 000 человек в сутки. Просто зашёл утром и увидел вместо главной страницы рекламу виагры на китайском языке. Хостинг заблокировал аккаунт за спам-рассылку с моего сервера, база данных была частично уничтожена, а восстановление заняло почти неделю. С тех пор я досконально изучил вопрос безопасности WordPress и внедрил систему защиты, которая с тех пор ни разу меня не подвела — ни на этом проекте, ни на десятке других, которыми я управляю сейчас.
Делюсь конкретными шагами как защитить сайт от взлома, без теории ради теории.
Почему WordPress ломают чаще всего
CMS занимает больше 40% всего рынка сайтов, поэтому боты сканируют её постоянно и автоматически. Взлом почти никогда не целевой — это конвейер: скрипт находит уязвимую версию плагина, эксплойт публичный, атака автоматизирована. Значит и защита должна быть системной, а не «поставил один плагин и забыл».
1. Обновления — это не опция, это обязанность
Больше 70% взломов WordPress происходят через устаревшие плагины и темы. Я завёл правило: обновления core, плагинов и темы проверяю каждую неделю, критические патчи — в течение 24 часов.
Автоматизировать это можно через wp-config.php:
// Автообновление минорных версий WordPress
define( 'WP_AUTO_UPDATE_CORE', 'minor' );
// Включить автообновление плагинов
add_filter( 'auto_update_plugin', '__return_true' );
Удаляю всё неиспользуемое — неактивные плагины и темы не безопасны просто потому что выключены, их файлы всё равно доступны на сервере.
2. Смена префикса таблиц базы данных
Стандартный префикс wp_ — первое, что проверяют SQL-инъекции. Меняю на что-то уникальное на этапе установки, а если сайт уже работает — через плагин типа «Change DB Prefix» или вручную:
RENAME TABLE wp_posts TO xk29_posts;
RENAME TABLE wp_options TO xk29_options;
-- и так далее для всех таблиц
После переименования обязательно обновляю wp-config.php:
$table_prefix = 'xk29_';
И правлю все ссылки на префикс в самих таблицах options и usermeta через SQL-запросы или специализированный плагин.
3. Двухфакторная аутентификация и жёсткие пароли
После инцидента я поставил Wordfence с обязательной 2FA для всех ролей выше подписчика. Это блокирует 99% брутфорс-атак даже если пароль скомпрометирован.
Дополнительно ограничиваю количество попыток входа через функцию в functions.php:
function limit_login_attempts() {
$ip = $_SERVER['REMOTE_ADDR'];
$attempts = get_transient( 'login_attempts_' . $ip );
if ( $attempts >= 5 ) {
wp_die( 'Слишком много попыток входа. Попробуйте через 15 минут.' );
}
}
add_action( 'wp_login_failed', function( $ip ) {
$ip = $_SERVER['REMOTE_ADDR'];
$attempts = get_transient( 'login_attempts_' . $ip );
set_transient( 'login_attempts_' . $ip, ( $attempts ? $attempts + 1 : 1 ), 900 );
});
add_action( 'wp_authenticate', 'limit_login_attempts' );
4. Скрытие страницы входа
Стандартный /wp-admin и /wp-login.php — первая цель ботов. Я перенёс страницу входа через плагин WPS Hide Login, но можно и вручную добавить в .htaccess редирект на кастомный URL с проверкой секретного параметра.
5. Файрвол на уровне .htaccess
Вот блок правил, который использую на каждом проекте — блокирует прямой доступ к чувствительным файлам:
# Запрет доступа к wp-config.php
<files wp-config.php>
order allow,deny
deny from all
</files>
# Запрет выполнения PHP в папке uploads
<Directory "/wp-content/uploads/">
<Files "*.php">
deny from all
</Files>
</Directory>
# Блокировка доступа к xmlrpc.php (частый вектор атак)
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
# Запрет просмотра содержимого директорий
Options -Indexes
xmlrpc.php я отключаю почти всегда — этот файл используется для DDoS через pingback и брутфорс-атак, а реально нужен только если вы публикуете посты через мобильное приложение WordPress.
6. Права доступа к файлам
Неправильные права — частая причина, по которой взлом происходит повторно даже после чистки. Правильная схема:
find /path/to/wordpress/ -type d -exec chmod 755 {} \;
find /path/to/wordpress/ -type f -exec chmod 644 {} \;
chmod 600 wp-config.php
Директории 755, файлы 644, wp-config.php — максимально закрыт, до 600.
7. Регулярные бэкапы с проверкой восстановления
Бэкап, который никогда не тестировался на восстановление — это не бэкап, это иллюзия безопасности. Я использую UpdraftPlus с автоматической выгрузкой на внешнее облачное хранилище (не на тот же сервер!) и периодически реально разворачиваю копию на тестовом окружении, чтобы убедиться, что она рабочая.
Расписание: ежедневный бэкап базы данных, еженедельный полный бэкап файлов.
8. Security-заголовки в HTTP-ответах
Добавляю в functions.php заголовки, которые усложняют жизнь атакующим:
function add_security_headers() {
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-Content-Type-Options: nosniff' );
header( 'X-XSS-Protection: 1; mode=block' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
}
add_action( 'send_headers', 'add_security_headers' );
Это защищает от clickjacking, MIME-сниффинга и части XSS-атак прямо на уровне браузера.
9. Мониторинг изменений файлов
Взлом часто остаётся незамеченным неделями. Я использую функцию сканирования целостности файлов внутри Wordfence, но базовую логику можно сделать и самостоятельно — cron-задача, которая сравнивает хэши файлов с эталонными и присылает уведомление при изменении.
10. Скрытие версии WordPress
Мелочь, но снижает точность автоматических сканеров:
function remove_wp_version() {
return '';
}
add_filter( 'the_generator', 'remove_wp_version' );
Что в итоге
За три года после внедрения этой системы ни один из моих проектов не был скомпрометирован, хотя атаки фиксируются логами почти ежедневно — их просто останавливает многослойная защита. Ключевой урок: безопасность WordPress не про один волшебный плагин, а про совокупность мелких барьеров, каждый из которых снижает вероятность успешной атаки. Начните с обновлений и бэкапов — это два пункта, которые спасут вас в 90% случаев, даже если остальное настроить не сразу.