🕐 13 хв читання

Чекліст безпеки 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);
Системний cron: */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) версій — вони часто містять бекдори.
~97% проблем безпеки WordPress пов'язані саме з плагінами (дані Patchstack).

Оновлення

  • Регулярно оновлюйте всі теми та плагіни.
  • Вимикайте та видаляйте невикористовувані модулі — навіть деактивований плагін може бути вразливим.
  • Підпишіться на сповіщення про критичні оновлення від розробників та баз вразливостей (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
Власник файлів — системний користувач (не root).

Налаштування вебсервера

Вимкнення лістингу директорій:

  • 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 в конфігурації.
  • Регулярна ротація пароля БД.
  • Використовуйте окремого користувача БД для кожного сайту на сервері.

Аутентифікація та контроль доступу

Реєстрація користувачів

Якщо сайт не потребує публічної реєстрації — вимкніть її: Налаштування → Загальне → зняти «Будь-хто може зареєструватися».

Банальний пункт, але часто забувають — відкрита реєстрація дає атакуючому авторизований доступ до REST API та внутрішніх ендпоінтів.

Паролі

  • Мінімум 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=Strict flags для 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');
});
Також приберіть віджет коментарів з дашборду та видаліть сторінку коментарів з admin bar.

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 або аналог.
  • Фіксуйте: логіни, встановлення/оновлення плагінів, зміни налаштувань, редагування контенту.
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) або серверні скрипти.
  • Зберігайте бекапи зашифрованими.
Обов'язково тестуйте відновлення з бекапу («репетиція пожежі»).
Окремо шифруйте дампи БД — вони містять паролі, email-адреси, персональні дані користувачів та токени. Незашифрований дамп БД в чужих руках = повна компрометація сайту.

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-проекту:

  1. Перевірити версію PHP (8.3+)
  2. Додати DISALLOW_FILE_EDIT та DISABLE_WP_CRON у wp-config.php
  3. Оновити Salts
  4. Налаштувати 2FA для всіх адмінів
  5. Закрити xmlrpc.php на рівні сервера
  6. Вимкнути pingbacks/trackbacks
  7. Вимкнути коментарі (якщо не потрібні проекту)
  8. Обмежити дозволені формати завантаження файлів (upload_mimes)
  9. Заблокувати виконання PHP в uploads/ та wp-includes/
  10. Видалити readme.html, license.txt, wp-config-sample.php
  11. Заблокувати user enumeration (author, REST API users)
  12. Приховати ID користувачів, постів та термів з публічної розмітки
  13. Видалити/понизити адмін-акаунти з ID 1–10, створити адміна з вищим ID
  14. Налаштувати Security Headers
  15. Налаштувати бекапи на зовнішнє сховище
  16. Встановити Activity Log плагін
  17. Перевірити файлові права (644/755/600)
  18. Налаштувати Cloudflare WAF
  19. Налаштувати rate limiting на wp-login.php на рівні сервера
  20. Фільтрація HTTP-методів (тільки GET/POST/HEAD)
  21. Налаштувати login notification для адмінів
  22. Налаштувати захист від hot-linking
  23. Налаштувати SPF/DKIM/DMARC
  24. Додати security.txt
  25. Вимкнути публічну реєстрацію (якщо не потрібна)
  26. Вимкнути oEmbed (якщо не потрібен)
  27. Додати X-Robots-Tag noindex для wp-admin
  28. Протестувати відновлення з бекапу
  29. Шифрувати дампи БД окремо
🔍
Почніть вводити назву лекції або тему