
🔒 HTTP Security Headers для WordPress: полный гайд по настройке
Сайт на WordPress работает, плагин безопасности установлен, но проверка на securityheaders.com выдаёт оценку F. Знакомо?
HTTP-заголовки безопасности — это невидимый слой защиты, о котором забывают даже после настройки файрвола и двухфакторной аутентификации. Они не требуют продления лицензии, не грузят сервер и закрывают целые классы атак: от кликджекинга до перехвата сессий. И добавляются за 10 минут.
Ниже, пошагово: какие заголовки действительно нужны, как их настроить через.htaccess, functions.php или плагин, и как проверить, что защита работает, а не просто числится.
💡 Быстрый обзор:
- Проверьте текущие заголовки сайта через securityheaders.com или Mozilla Observatory, увидите реальную картину
- Включите базовый набор из 4-5 заголовков: X-Content-Type-Options, X-Frame-Options, HSTS, Referrer-Policy, Permissions-Policy
- Выберите способ: пара строк в.htaccess (Apache/LiteSpeed), сниппет в functions.php или плагин Headers Security Advanced & HSTS WP
- CSP оставляйте на потом, сложный в настройке и ломает Gutenberg, если сделан без тестирования
- После внедрения пройдите повторную проверку, оценка A+ достижима за 10 минут
Что такое HTTP Security Headers
Когда браузер запрашивает страницу, веб-сервер отдаёт не только HTML-код. Каждый HTTP-ответ содержит служебные поля, заголовки. Часть из них отвечает за кеширование и тип контента, а часть, за безопасность.
Браузер читает security-заголовки ещё до того, как начнёт рендерить страницу. Если сервер говорит «запрещаю встраивать этот сайт во фреймы», браузер не станет этого делать, даже если в коде страницы прописан <iframe>. Если сервер говорит «год работаем только по HTTPS», браузер запомнит и не пойдёт на HTTP-версию, даже если пользователь вручную её наберёт.
Никакой JavaScript, никакой плагин, никакой файрвол на это не влияют. Это уровень протокола. Именно поэтому заголовки, отдельный, самостоятельный рубеж защиты.
Зачем это WordPress-сайту
Плагины безопасности вроде Wordfence или Solid Security закрывают уязвимости на уровне приложения: брутфорс, инъекции, вредоносные загрузки. HTTP-заголовки работают на уровень выше, они защищают сам канал связи между сервером и посетителем.
Вот что закрывают правильно настроенные заголовки:
Кликджекинг. Злоумышленник встраивает ваш сайт в прозрачный фрейм поверх своего и перехватывает клики пользователя. Закрывается заголовком
X-Frame-Optionsили директивойframe-ancestorsв CSP.MIME-сниффинг. Браузер пытается «угадать» тип файла и может выполнить загруженное изображение как JavaScript. Закрывается
X-Content-Type-Options: nosniff.Перехват сессии. Злоумышленник на открытом Wi-Fi подменяет ответ сервера и крадёт cookie входа. HSTS запрещает браузеру ходить на HTTP-версию сайта.
Утечка реферера. При переходе по внешней ссылке сайт-назначение видит, с какой страницы пришёл пользователь, включая URL с параметрами. Referrer-Policy это ограничивает.
Несанкционированный доступ к устройствам. Веб-страница запрашивает микрофон, камеру или геолокацию без ведома пользователя. Permissions-Policy запрещает такие запросы на уровне браузера.
CSP добавляет ещё один слой: вы точно задаёте, с каких доменов можно грузить скрипты, стили и шрифты. Даже если вредоносный код попал в базу данных, браузер не выполнит его, потому что источник не в белом списке. Но CSP требует аккуратности: чуть ошибётесь, и редактор Gutenberg перестанет работать.
Ключевые HTTP-заголовки безопасности: что включает и зачем
Ниже, заголовки, которые имеет смысл настраивать на любом WordPress-сайте. Для каждого указано: от какой атаки защищает, рекомендуемое значение и где может сломаться.
X-Content-Type-Options
Самый простой и безопасный в настройке. Единственное допустимое значение, nosniff. Браузер перестаёт «угадывать» MIME-тип файла по содержимому и доверяет только тому типу, который передал сервер в заголовке Content-Type.
Без этого заголовка браузер может принять загруженное пользователем изображение за скрипт и выполнить его, классический сценарий атаки через загрузку файлов.
Рекомендуемое значение: nosniff
Риски поломок: минимальны. Проблемы возможны только если сервер отдаёт файлы с неправильным Content-Type, но это отдельная проблема, которую стоит исправить, а не маскировать.
X-Frame-Options
Контролирует, может ли ваш сайт быть встроен в <frame>, <iframe> или <object> на чужом сайте.
Два основных значения:
DENY, полный запрет встраивания. Максимальная защита.SAMEORIGIN, разрешено встраивание только с того же домена. Нужно, если вы сами используете фреймы для своих же страниц (например, предпросмотр в админке).
Для большинства WordPress-сайтов подходит SAMEORIGIN. Если вы точно знаете, что никакие фреймы не используются, ставьте DENY.
Рекомендуемое значение: SAMEORIGIN
Риски поломок: некоторые плагины используют iframe для предпросмотра. Если после включения DENY что-то перестало отображаться в админке, переключитесь на SAMEORIGIN.
Strict-Transport-Security (HSTS)
Говорит браузеру: «ближайшие N секунд ходи на этот домен только по HTTPS». Защищает от downgrade-атак и перехвата cookie на открытых сетях.
Ключевой параметр, max-age. Рекомендуется начинать с небольшого значения (сутки или неделя) и после проверки увеличивать до года.
Опциональный параметр includeSubDomains распространяет правило на все поддомены, важно, если у вас их несколько и вы используете CDN.
Параметр preload включает сайт в глобальный HSTS-список браузеров: Chrome, Firefox и Safari будут ходить на ваш домен только по HTTPS ещё до первого запроса. Подача заявки, через hstspreload.org.
Рекомендуемое значение: max-age=31536000; includeSubDomains
Риски поломок: если включить HSTS, а SSL-сертификат истечёт, пользователи вообще не попадут на сайт. Следите за автообновлением сертификата.
Referrer-Policy
Управляет тем, какую информацию о странице-источнике браузер передаёт при переходе по ссылке на другой сайт.
Основные значения, от самого строгого к самому мягкому:
no-referrer, вообще ничего не передаётся.strict-origin-when-cross-origin, на другой домен передаётся только домен (без пути и параметров); на свой, полный URL. Оптимальный баланс приватности и аналитики.strict-origin, всегда только домен, без пути.
Если вы вообще не хотите, чтобы сайты-назначения знали, откуда пришёл пользователь, ставьте no-referrer. Но имейте в виду: вы потеряете реферальный трафик в своей же аналитике.
Рекомендуемое значение: strict-origin-when-cross-origin
Риски поломок: минимальны. Некоторые сторонние сервисы могут требовать реферер для работы (например, шлюзы оплаты с проверкой источника). Отследить такие случаи можно через консоль браузера.
Permissions-Policy
Раньше назывался Feature-Policy. Ограничивает доступ веб-страницы к «железным» API браузера: микрофону, камере, геолокации, USB, платежным API и так далее.
Формат: название-фичи=(разрешённый-источник). Например:
1 Permissions-Policy: camera=(), microphone=(), geolocation=(self)
Этот пример полностью запрещает доступ к камере и микрофону для всех источников, а геолокацию разрешает только для самого сайта (self).
Полный список фич, на MDN. Для WordPress-сайта без видеочатов и PWA-функций достаточно закрыть камеру, микрофон и геолокацию, остальное опционально.
Рекомендуемое значение: зависит от функционала сайта. Минимум, camera=(), microphone=(), geolocation=(self).
Риски поломок: если на сайте есть функционал видеозвонков, PWA или WebUSB, проверьте, какие фичи ему нужны, и не закрывайте их.
Content-Security-Policy (CSP)
Самый мощный и самый опасный в настройке заголовок. Определяет белый список источников для скриптов, стилей, шрифтов, изображений, фреймов и других ресурсов.
Пример минимальной политики для WordPress:
1 Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; 2
*Почему unsafe-inline и unsafe-eval:* WordPress, Gutenberg и десятки плагинов генерируют inline-скрипты и используют eval(). Без этих директив админка просто перестанет работать. Это плата за совместимость.
Рекомендация: не включайте CSP первым делом. Сначала настройте остальные 5 заголовков. CSP внедряйте только если у вас есть ресурс на тестирование и мониторинг, начните с режима Content-Security-Policy-Report-Only и собирайте логи нарушений пару недель, прежде чем переходить в enforce-режим.
Риски поломок: высокие. Ошибка в CSP может полностью сломать фронтенд и админку. Всегда тестируйте на стейдже или через Report-Only.
Как проверить текущие заголовки сайта
Перед настройкой, аудит. Три инструмента, от простого к детальному:
securityheaders.com, вводите URL и получаете оценку от A+ до F с расшифровкой по каждому заголовку. Бесплатно, без регистрации.
Mozilla Observatory, более детальный аудит: оценивает не только заголовки, но и TLS-настройки, cookie-атрибуты, CORS и другие аспекты. Тоже бесплатно.
Chrome DevTools, откройте вкладку Network, выберите любой запрос к вашему сайту и посмотрите секцию Response Headers. Быстрый способ проверить, «взлетели» ли изменения после правки.htaccess.
Проверьте сайт прямо сейчас. Если оценка ниже B, у вас нет даже базовых заголовков, и треть пунктов ниже вы поставите за 5 минут.
Способы настройки HTTP-заголовков в WordPress
Три пути, от ручного к автоматическому. Выбирайте под свою ситуацию.
Способ 1: Через.htaccess (Apache/LiteSpeed)
Самый быстрый способ для сайтов на Apache или LiteSpeed. Добавьте в .htaccess в корне сайта (перед # BEGIN WordPress):
1 <IfModule mod_headers.c> 2 Header set X-Content-Type-Options "nosniff" 3 Header set X-Frame-Options "SAMEORIGIN" 4 Header set Strict-Transport-Security "max-age=31536000; includeSubDomains" 5 Header set Referrer-Policy "strict-origin-when-cross-origin" 6 Header set Permissions-Policy "camera=(), microphone=(), geolocation=(self)" 7 </IfModule>
Оболочка <IfModule mod_headers.c> гарантирует, что сайт не упадёт с ошибкой 500, если модуль mod_headers не включён. Если вы точно знаете, что он активен, можно без неё.
После сохранения выполните в терминале (если есть WP-CLI) или просто откройте сайт и проверьте заголовки через securityheaders.com. Изменения в .htaccess применяются мгновенно, перезагрузка сервера не нужна.
Способ 2: Через functions.php (Nginx / универсальный)
Работает независимо от веб-сервера, подходит и для Nginx, и для Apache. Добавьте в functions.php дочерней темы или через плагин Code Snippets:
1 function sdstudio_add_security_headers() { 2 header( 'X-Content-Type-Options: nosniff' ); 3 header( 'X-Frame-Options: SAMEORIGIN' ); 4 header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains' ); 5 header( 'Referrer-Policy: strict-origin-when-cross-origin' ); 6 header( 'Permissions-Policy: camera=(), microphone=(), geolocation=(self)' ); 7 } 8 add_action( 'send_headers', 'sdstudio_add_security_headers' );
Хук send_headers срабатывает раньше, чем WordPress начнёт отдавать контент, заголовки уходят в самом первом ответе сервера.
Для Nginx этот способ предпочтительнее, чем лезть в конфигурацию сервера (особенно на shared-хостинге, где доступа к nginx.conf часто нет). Минус, заголовки работают только для PHP-запросов, проходящих через WordPress. Статические файлы (изображения, CSS, JS) обслуживаются Nginx напрямую и заголовков не получат. Для них потребуется конфигурация на уровне сервера.
Способ 3: Через плагин Headers Security Advanced & HSTS WP
Если не хотите трогать код, используйте специальный плагин. Headers Security Advanced & HSTS WP собирает все security-заголовки в одном интерфейсе и включает их одной кнопкой.

Плагин ставит предустановленные значения для всех ключевых заголовков сразу после активации, X-Content-Type-Options, X-Frame-Options, HSTS, CSP, Referrer-Policy, Permissions-Policy и ряд дополнительных (CORP, COOP, COEP). Каждый заголовок можно отключить или перенастроить под себя.
Плюс подхода: плагин не зависит от веб-сервера и работает одинаково на Apache, Nginx, LiteSpeed и IIS. При деактивации возвращает конфигурацию сайта в исходное состояние.
Альтернатива: Redirection
Плагин Redirection известен как менеджер редиректов, но умеет и добавлять HTTP-заголовки. После установки и базовой настройки перейдите в раздел Site → Headers, интерфейс позволяет прописать любые пары «заголовок: значение».

Этот вариант подойдёт, если Redirection у вас уже стоит для управления ссылками и вы не хотите добавлять ещё один плагин. Но специальный плагин заголовков даёт больше контроля и предустановленные значения.
На видео, наглядная демонстрация настройки заголовков через плагин Headers Security Advanced: от установки до проверки результата на securityheaders.com.
⁉️🤔 Частые вопросы
Что делать, если после включения заголовков сайт сломался?
Первым делом проверьте заголовок Content-Security-Policy, именно он вызывает подавляющее большинство поломок. Отключите CSP (или переключите в режим Report-Only) и проверьте сайт снова. Ошибка 500 после правки.htaccess, проверьте синтаксис: лишний пробел, незакрытые кавычки или отсутствие модуля mod_headers. Через FTP переименуйте.htaccess → сайт оживёт, и вы сможете спокойно найти ошибку.
В 9 из 10 случаев проблема именно в CSP, а не в остальных заголовках. X-Content-Type-Options, X-Frame-Options, HSTS и Referrer-Policy сломать сайт не могут физически, они не затрагивают рендеринг и логику PHP. Начинайте всегда с них.
Обязательно ли использовать плагин или можно через код?
Можно и нужно через код, если вы умеете править functions.php или.htaccess. Прямая установка заголовков через конфигурацию сервера работает быстрее плагина, нет прослойки PHP. Но плагин удобнее для тех, кто не хочет лезть в код, и даёт визуальный интерфейс с предустановками для каждого заголовка.
Мы на тестовых сайтах используем оба подхода: на продакшене,.htaccess (меньше точек отказа), на клиентских сайтах где хостинг не даёт править конфигурацию, плагин. Результат по securityheaders.com идентичен: A+ в обоих случаях.
Нужно ли настраивать CSP, если сайт на WordPress?
Для большинства сайтов, нет. CSP на WordPress требует unsafe-inline и unsafe-eval для работы Gutenberg и десятков плагинов — это снижает защитный эффект до символического. Полноценный CSP имеет смысл на высоконагруженных проектах с выделенным специалистом по безопасности, который будет разбирать каждый отчёт о нарушении. Для всех остальных 5 базовых заголовков дают львиную долю практической защиты.
Как проверить, что заголовки работают после установки?
Откройте сайт в браузере, запустите DevTools (F12) → вкладка Network → кликните на первый запрос к вашему домену → секция Response Headers. Если видите добавленные заголовки, всё работает. Для автоматической проверки используйте securityheaders.com, он показывает не только наличие, но и корректность значений, а также итоговую оценку от A+ до F.
Что делать, если хостинг не даёт править.htaccess и нет доступа к functions.php?
Установите Headers Security Advanced & HSTS WP через админку WordPress. Плагин внедряет заголовки на уровне PHP и не требует правки серверных файлов. Это работает на любом хостинге, где крутится WordPress, от дешёвого shared до Managed WordPress.
Влияют ли HTTP-заголовки на скорость сайта?
Практически нет. Заголовки — это пара десятков байт текста в ответе сервера. Они не выполняют вычислений, не делают запросов к базе данных, не грузят процессор. Задержка, которую они добавляют, измеряется микросекундами. Единственное исключение, CSP со сложным белым списком из сотен доменов: браузер тратит время на парсинг, но даже в этом случае влияние на скорость отрисовки не превышает пары миллисекунд.
Что ставить и с чего начать
HTTP-заголовки безопасности, не разовая акция «поставил и забыл». Это baseline, который должен быть на каждом сайте по умолчанию, как SSL-сертификат.
План на сегодня:
Проверьте сайт на securityheaders.com. Если оценка D или F, у вас нет даже
X-Content-Type-Options.Добавьте 5 базовых заголовков любым из трёх способов выше. Если сайт на Apache, через.htaccess (30 секунд). Nginx без доступа к конфигу, через functions.php (2 минуты). Не хотите код, плагин Headers Security Advanced (3 минуты с установкой).
Перепроверьте сайт. Оценка должна подняться до A или A+.
CSP отложите. Вернитесь к нему, когда базовые заголовки отработают месяц без проблем, а у вас появится время на тестирование через Report-Only.
Один час, и у вашего WordPress-сайта появляется эшелон защиты, которого нет у подавляющего большинства сайтов в интернете. Начните с проверки прямо сейчас.


