Чекліст безпеки WordPress (2026)
Комплексний чекліст захисту WordPress-проєкту: від конфігурації ядра до мережевого рівня.
Ядро WordPress: оновлення та hardening
Оновлення
- Завжди тримайте WordPress в актуальному стані — старі версії не отримують патчів безпеки.
- Увімкніть автооновлення для minor-версій ядра.
- Перед major-оновленнями робіть резервну копію та перевіряйте на staging-середовищі.
- Завантажуйте ядро виключно з wordpress.org. Ніяких nulled або модифікованих збірок.
- Регулярно перевіряйте цілісність файлів ядра через WP-CLI:
wp core verify-checksums. - Видаліть з кореня сайту файли, що розкривають версію WP та інші деталі:
readme.html,license.txt,wp-config-sample.php. Вони відновлюються при оновленні ядра — автоматизуйте видалення через deploy-скрипт або cron.
Конфігурація wp-config.php
Вимкнення редагування файлів через адмінку — захист від RCE, вимикає Theme Editor і Plugin Editor одночасно:
define('DISALLOW_FILE_EDIT', true);
Заборона встановлення/оновлення плагінів/тем — тільки для production з CI/CD:
define('DISALLOW_FILE_MODS', true);
Примусовий SSL для адмінки:
define('FORCE_SSL_ADMIN', true);
Вимкнення вбудованого wp-cron — замінити на системний cron:
define('DISABLE_WP_CRON', true);
*/15 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Вимкнення режиму дебагу на production:
define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);
define('WP_DEBUG_LOG', false);
Унікальні ключі безпеки (Salts)
- Згенеруйте через WordPress.org Salt Generator.
- Оновлення ключів «скидає» всі активні сесії.
- Ротуйте ключі після будь-якого інциденту безпеки.
Захист wp-config.php
- Перемістіть файл на рівень вище за кореневу теку вебсервера.
- Права доступу:
600або640. - Заблокуйте доступ через веб-сервер (див. розділ «Серверне середовище»).
Теми та плагіни
Вибір та джерело
- Встановлюйте тільки з офіційного каталогу WordPress.org або перевірених маркетплейсів.
- Перед встановленням оцініть: дата останнього оновлення, рейтинг, кількість активних інсталяцій, відгуки (особливо щодо безпеки).
- Уникайте «піратських» (nulled) версій — вони часто містять бекдори.
Оновлення
- Регулярно оновлюйте всі теми та плагіни.
- Вимикайте та видаляйте невикористовувані модулі — навіть деактивований плагін може бути вразливим.
- Підпишіться на сповіщення про критичні оновлення від розробників та баз вразливостей (Patchstack, WPScan).
Аудит та перевірка
- Скануйте плагіни/теми на вразливості та шкідливий код: WPScan, Sucuri SiteCheck, Patchstack, Wordfence.
- Для платних тем/плагінів — перевіряйте наявність аудиту безпеки від розробника.
- Тестуйте нові розширення спочатку на локальному чи staging-сервері.
- Перевіряйте зовнішні залежності (Composer, npm) на оновлення та CVE.
Supply Chain Security
- Використовуйте Subresource Integrity (SRI) для зовнішніх скриптів та стилів.
- Контролюйте checksums завантажених пакетів.
- Слідкуйте за supply chain атаками через бази CVE.
Серверне середовище
PHP
- Використовуйте PHP 8.3 або 8.4 (стандарт для 2026). Версії нижче 8.1 — ризик.
- Приховуйте версію PHP:
expose_php = Off. - Налаштуйте
open_basedirдля обмеження доступу PHP до файлової системи.
Вимкніть небезпечні функції в php.ini:
disable_functions = exec, passthru, shell_exec, system, proc_open, popen, curl_multi_exec, parse_ini_file, show_source
Файлові права
| Об'єкт | Права |
|---|---|
| Файли WordPress | 644 (або 640) |
| Каталоги | 755 (або 750) |
wp-config.php |
600 |
Налаштування вебсервера
Вимкнення лістингу директорій:
- Apache:
Options -Indexesу.htaccess. - Nginx:
autoindex off;.
Заборона виконання PHP в uploads:
Apache (.htaccess в wp-content/uploads/):
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
Nginx:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
Заборона виконання PHP в wp-includes:
Nginx:
location ~* /wp-includes/.*\.php$ {
deny all;
}
Apache (.htaccess в wp-includes/):
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
wp-includes/ms-files.php потрібен для Multisite.
Блокування доступу до системних файлів:
Apache:
<FilesMatch "^(wp-config\.php|\.htaccess|\.git|\.env|\.svn|readme\.html|license\.txt)">
Require all denied
</FilesMatch>
Nginx:
location ~ /(\.|wp-config\.php|readme\.html|license\.txt) {
deny all;
}
Блокування xmlrpc.php на рівні сервера:
Apache:
<Files xmlrpc.php>
Require all denied
</Files>
Nginx:
location = /xmlrpc.php {
deny all;
}
Security Headers
Налаштуйте через конфіг вебсервера або .htaccess:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Permitted-Cross-Domain-Policies: none
Content-Security-Policy: [налаштовуйте обережно під конкретний проект]
Заборона індексації адмінки
Додайте X-Robots-Tag: noindex, nofollow для /wp-admin/ та /wp-login.php, щоб пошуковики не індексували службові сторінки:
Nginx:
location ~* ^/(wp-admin|wp-login\.php) {
add_header X-Robots-Tag "noindex, nofollow" always;
}
SSL/TLS
- Встановіть SSL-сертифікат (Let's Encrypt або комерційний).
- Перенаправляйте весь HTTP-трафік на HTTPS.
- Увімкніть HSTS.
SSH
- Використовуйте SSH з ключами (не паролем).
- Змініть стандартний порт SSH.
- Використовуйте Fail2Ban для блокування підозрілих спроб підключення.
Обмеження розміру запитів
Захист від DoS через великі upload. Налаштуйте ліміт на рівні вебсервера:
- Nginx:
client_max_body_size 10m; - Apache:
LimitRequestBody 10485760
upload_max_filesize та post_max_size в php.ini.
Фільтрація HTTP-методів
Дозволяйте тільки GET, POST, HEAD для публічних сторінок. Блокуйте TRACE, DELETE, PUT, OPTIONS (якщо не потрібні для REST API):
Nginx:
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405;
}
Rate Limiting на рівні сервера
Окремо від плагінів, налаштуйте rate limiting для wp-login.php та xmlrpc.php:
Nginx:
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
location = /wp-login.php {
limit_req zone=login burst=3 nodelay;
include fastcgi_params;
fastcgi_pass php;
}
Захист від hot-linking
Заборона прямого підключення зображень з інших сайтів (bandwidth theft):
Nginx:
location ~* \.(jpg|jpeg|png|gif|webp|svg)$ {
valid_referers none blocked server_names *.yourdomain.com;
if ($invalid_referer) {
return 403;
}
}
База даних
Конфігурація
- Змініть дефолтний префікс
wp_на рандомний (наприклад,x7z_) на етапі встановлення. - Обмежте права користувача БД: тільки
SELECT,INSERT,UPDATE,DELETE. БезDROP,ALTER,CREATE,GRANT(якщо це можливо в робочому режимі). - Обмежте віддалений доступ до MySQL:
bind-address = 127.0.0.1в конфігурації. - Регулярна ротація пароля БД.
- Використовуйте окремого користувача БД для кожного сайту на сервері.
Аутентифікація та контроль доступу
Реєстрація користувачів
Якщо сайт не потребує публічної реєстрації — вимкніть її: Налаштування → Загальне → зняти «Будь-хто може зареєструватися».
Паролі
- Мінімум 12 символів: великі/малі літери, цифри, спецсимволи.
- Перевіряйте паролі через базу HaveIBeenPwned.
- Використовуйте менеджер паролів.
- Регулярна ротація паролів.
Двофакторна автентифікація (2FA)
- Обов'язково для всіх адміністраторів та редакторів.
- SMS — це legacy. Використовуйте:
- Passkeys (біометрія, FIDO2) — найкращий варіант.
- TOTP (Google Authenticator, Authy) — добрий варіант.
- Плагіни: WP 2FA, Solid Security.
Захист форми входу
- Обмеження спроб входу: блокування IP після 3–5 невдалих спроб на 10–20 хвилин (Limit Login Attempts Reloaded або аналог).
- CAPTCHA (reCAPTCHA) на форму входу та публічні форми.
- Зміна URL входу з
/wp-adminна кастомний (security through obscurity, але ефективний фільтр шуму від ботів). - За можливості — обмеження доступу до сторінки входу за IP через
.htaccessабо firewall.
Application Passwords
Для REST API інтеграцій (n8n, Zapier тощо) використовуйте Application Passwords замість реального пароля адміна.
Принцип найменших привілеїв
- Адміністративну роль — тільки довіреним користувачам.
- Іншим — мінімально необхідні ролі.
- Не пишіть контент від імені адміністратора — створіть окремий обліковий запис «Автор» або «Редактор» для публікацій. Адмін-акаунт не повинен бути автором жодного посту.
- Регулярно перевіряйте список користувачів, видаляйте непотрібні акаунти.
- Не залишайте логін
adminабоadministrator.
User ID адміністраторів
- Видаліть або понизьте роль користувачів з ID 1–10 (боти та скрипти brute-force атакують саме ці ID в першу чергу).
- Створіть робочий адмін-акаунт з непередбачуваним ID (наприклад, 8+ або далі).
- Перепризначте контент видалених користувачів на обліковий запис автора.
Сесії та cookies
- Встановіть
Secure,HttpOnly,SameSite=Strictflags для cookies. - Обмежте час життя сесій адміністраторів.
- Автоматичне завершення сесії неактивних користувачів (плагін Idle User Logout).
- Автоматичний logout всіх сесій користувача при зміні його ролі або пароля іншим адміном — запобігає ситуації, коли понижений або звільнений користувач зберігає активну сесію.
API та інтерфейси
XML-RPC
У 2026 році практично не потрібен (замінений REST API), але залишається вектором DDoS та brute-force атак. Вимкніть через фільтр:
add_filter('xmlrpc_enabled', '__return_false');
xmlrpc.php на рівні вебсервера (див. розділ «Серверне середовище»).
WordPress Embeds (oEmbed)
Якщо функціональність вбудовування контенту (embed) не потрібна — вимкніть її для зменшення attack surface:
// Видалити oEmbed discovery links
remove_action('wp_head', 'wp_oembed_add_discovery_links');
// Видалити oEmbed JavaScript
remove_action('wp_head', 'wp_oembed_add_host_js');
// Вимкнути oEmbed endpoint
add_filter('embed_oembed_discover', '__return_false');
// Деактивувати embed rewrite rules
remove_action('rest_api_init', 'wp_oembed_register_route');
Коментарі
Якщо проект не потребує коментування на фронтенді — вимкніть коментарі повністю на рівні ядра. Відкриті коментарі — це вектор спаму, XSS та SQL-ін'єкцій через сторонні плагіни коментування.
- В адмінці: Налаштування → Обговорення → зняти «Дозволити коментарі до нових записів».
Для повного вимкнення (включно з існуючими записами):
// Вимкнути підтримку коментарів для всіх типів контенту
add_action('admin_init', function() {
$post_types = get_post_types();
foreach ($post_types as $post_type) {
remove_post_type_support($post_type, 'comments');
remove_post_type_support($post_type, 'trackbacks');
}
});
// Закрити коментарі на фронтенді
add_filter('comments_open', '__return_false', 20, 2);
add_filter('pings_open', '__return_false', 20, 2);
// Сховати існуючі коментарі
add_filter('comments_array', '__return_empty_array', 10, 2);
// Прибрати пункт меню «Коментарі» з адмінки
add_action('admin_menu', function() {
remove_menu_page('edit-comments.php');
});
Pingbacks та Trackbacks
Вимкніть повністю — це застарілий функціонал, який використовується як вектор DDoS-ампліфікації та спаму.
- В адмінці: Налаштування → Обговорення → зняти «Дозволити сповіщення посилань з інших блогів (pingbacks та trackbacks)».
Додатково через код:
add_filter('xmlrpc_methods', function($methods) {
unset($methods['pingback.ping']);
unset($methods['pingback.extensions.getPingbacks']);
return $methods;
});
add_filter('wp_headers', function($headers) {
unset($headers['X-Pingback']);
return $headers;
});
REST API
Обмеження REST API для анонімних користувачів:
- Звичайний корпоративний сайт
- Лендінг
- Блог без зовнішніх інтеграцій та headless-архітектури
- Headless WP (React/Vue/Next.js)
- WooCommerce з зовнішніми інтеграціями
- Плагіни форм або кешування що працюють через REST
- Gutenberg-блоки на фронтенді що тягнуть дані через API
Оптимальний підхід — не вимикати повністю, а селективно закрити небезпечні ендпоінти (як мінімум /wp/v2/users) і дозволити тільки потрібні namespace (наприклад, contact-form-7, oembed).
Обмежте доступ до ендпоінтів, що лістять користувачів (/wp-json/wp/v2/users):
add_filter('rest_endpoints', function($endpoints) {
if (isset($endpoints['/wp/v2/users'])) {
unset($endpoints['/wp/v2/users']);
}
if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)'])) {
unset($endpoints['/wp/v2/users/(?P<id>[\d]+)']);
}
return $endpoints;
});
Якщо REST API не використовується публічно — обмежте доступ тільки для авторизованих користувачів.
User Enumeration
Заблокуйте /?author=N enumeration:
if (!is_admin() && isset($_GET['author'])) {
wp_redirect(home_url(), 301);
exit;
}
Або через .htaccess / Nginx rewrite.
Приховування ID (Posts, Users, Terms)
Сховайте числові ID користувачів, постів та термів з публічних URL і HTML-розмітки — вони спрощують enumeration та targeted атаки.
- Користувачі: використовуйте slug замість ID в author archives; приберіть ID з body class (
author-1) через фільтрbody_class. - Пости: за можливості використовуйте ЧПУ (pretty permalinks) без числових ID.
Видаліть ID з CSS-класів (post-123, page-item-45):
add_filter('post_class', function($classes) {
return array_filter($classes, function($class) {
return !preg_match('/^(post|page-item)-\d+$/', $class);
});
});
Терми: аналогічно приберіть ID з класів меню та віджетів (menu-item-123, cat-item-5):
add_filter('nav_menu_css_class', function($classes) {
return array_filter($classes, function($class) {
return !preg_match('/^menu-item-\d+$/', $class);
});
});
Приберіть <meta name="generator"> з head:
remove_action('wp_head', 'wp_generator');
File Uploads
- Валідація MIME-типів завантажуваних файлів (не покладатися тільки на розширення).
- Заборона виконання PHP в
wp-content/uploads/(див. розділ «Серверне середовище»). - Сканування завантажених файлів на шкідливий код.
Строго обмежте дозволені типи файлів через фільтр upload_mimes — залиште тільки ті формати, які реально потрібні проекту. За замовчуванням WordPress дозволяє десятки типів (включно з SVG у нових версіях), більшість з яких не потрібні:
add_filter('upload_mimes', function($mimes) {
return [
'jpg|jpeg|jpe' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'webp' => 'image/webp',
'pdf' => 'application/pdf',
];
});
.svg (XSS-вектор без санітизації), .exe, .php, .sh, .sql.
Content-Disposition header — налаштуйте сервер віддавати файли з uploads з заголовком Content-Disposition: attachment, щоб браузер не виконував їх, а пропонував скачати:
Nginx:
location ~* /wp-content/uploads/ {
add_header Content-Disposition "attachment";
}
WAF та мережевий захист
Зовнішній WAF (CDN)
- Cloudflare (або Sucuri, Cloud Armor) — рекомендовано для всіх проектів.
- CDN приховує реальну IP-адресу сервера та захищає від DDoS.
Налаштуйте WAF Rules:
- Block доступ до
xmlrpc.php. - Challenge (Captcha) для
/wp-adminдля всіх країн, окрім вашої. - Block запити з підозрілими User-Agent.
- Rate limiting на критичні ендпоінти.
Внутрішній WAF (плагіни)
- Wordfence, Solid Security або аналоги — для захисту на рівні WordPress.
- Моніторинг та блокування підозрілих запитів.
Мережевий фаєрвол
- Налаштуйте iptables/ufw: закрийте всі порти, окрім необхідних (SSH, HTTPS).
- Fail2Ban або OSSEC для автоматичного блокування підозрілих IP.
Моніторинг та логування
Activity Log
- Встановіть WP Activity Log або аналог.
- Фіксуйте: логіни, встановлення/оновлення плагінів, зміни налаштувань, редагування контенту.
Login Notification
Налаштуйте email-повідомлення адміну при кожному вході в адмінку — дозволяє оперативно виявити несанкціонований доступ, навіть якщо атакуючий обійшов інші шари захисту.
File Integrity Monitoring
- Відстежуйте зміни хешів файлів ядра, плагінів та тем (Wordfence, OSSEC).
wp core verify-checksums— регулярно через cron.
Серверні логи
- Регулярно аналізуйте access та error логи на підозрілу активність.
- Налаштуйте алерти на аномальну кількість 404, 403 або спроб доступу до адмінки.
Резервні копії
- Мінімум 3 копії на різних сховищах (сервер + хмара: S3, Google Drive, Backblaze).
- Ніколи не зберігайте бекапи тільки на тому ж сервері.
- Регулярність: щоденно для активних сайтів, щотижня для статичних.
- Інкрементальні + повні бекапи.
- Автоматизуйте через плагіни (UpdraftPlus, BlogVault) або серверні скрипти.
- Зберігайте бекапи зашифрованими.
DNS та Email Security
DNS
- Увімкніть DNSSEC для захисту від DNS spoofing.
- Приховуйте реальну IP сервера за CDN (Cloudflare тощо).
Email (захист домену від фішингу)
| Запис | Призначення |
|---|---|
| SPF | Вкажіть дозволені сервери відправки пошти |
| DKIM | Цифровий підпис листів |
| DMARC | Політика обробки листів, що не пройшли перевірку |
Disclosure та документація
security.txt
Додайте файл /.well-known/security.txt (RFC 9116) для responsible disclosure:
Contact: mailto:security@example.com
Preferred-Languages: uk, en
Expires: 2027-01-01T00:00:00.000Z
Документація
- Описуйте всі налаштування безпеки (без паролів у відкритому вигляді).
- Розробіть план відновлення після інциденту (DRP).
- Регулярно оновлюйте документацію.
Безпека робочого місця адміністратора
- Актуальна ОС, браузер, антивірус/EDR.
- Не використовуйте адмін-акаунт для звичайного серфінгу.
- Уникайте публічних Wi-Fi при роботі з сайтом; використовуйте VPN.
- Навчайте команду: фішинг, соціальна інженерія, обов'язковість 2FA.
- Призначте відповідального за моніторинг безпеки.
Action Plan (швидкий старт)
Мінімальний набір дій для базового захисту нового WordPress-проекту:
- Перевірити версію PHP (8.3+)
- Додати
DISALLOW_FILE_EDITтаDISABLE_WP_CRONуwp-config.php - Оновити Salts
- Налаштувати 2FA для всіх адмінів
- Закрити
xmlrpc.phpна рівні сервера - Вимкнути pingbacks/trackbacks
- Вимкнути коментарі (якщо не потрібні проекту)
- Обмежити дозволені формати завантаження файлів (
upload_mimes) - Заблокувати виконання PHP в
uploads/таwp-includes/ - Видалити
readme.html,license.txt,wp-config-sample.php - Заблокувати user enumeration (author, REST API users)
- Приховати ID користувачів, постів та термів з публічної розмітки
- Видалити/понизити адмін-акаунти з ID 1–10, створити адміна з вищим ID
- Налаштувати Security Headers
- Налаштувати бекапи на зовнішнє сховище
- Встановити Activity Log плагін
- Перевірити файлові права (644/755/600)
- Налаштувати Cloudflare WAF
- Налаштувати rate limiting на
wp-login.phpна рівні сервера - Фільтрація HTTP-методів (тільки GET/POST/HEAD)
- Налаштувати login notification для адмінів
- Налаштувати захист від hot-linking
- Налаштувати SPF/DKIM/DMARC
- Додати
security.txt - Вимкнути публічну реєстрацію (якщо не потрібна)
- Вимкнути oEmbed (якщо не потрібен)
- Додати X-Robots-Tag noindex для wp-admin
- Протестувати відновлення з бекапу
- Шифрувати дампи БД окремо