2026年11月12日
2026年11月12日
Как скрыть версию WordPress: тег generator, ver=, readme.html
Эта статья — локализованная версия японского оригинала. Читать японский оригинал
По умолчанию WordPress выводит номер своей версии в HTML страниц и в фидах. Злоумышленник может по нему определить, есть ли в этой версии известные уязвимости. В статье показано, где отображается версия и как её скрыть. Материал актуален на октябрь 2026 года.
Сначала нужно понимать, что скрытие версии — вспомогательная мера. Версию можно угадать, например, по содержимому файлов CSS и JavaScript, поэтому даже после скрытия определение версии не обязательно станет невозможным. Лучше всего помогает поддержание ядра WordPress, плагинов и тем в актуальном состоянии.
Где отображается версия
| Где | Что отображается | Что делать |
|---|---|---|
<head> в HTML |
Тег вроде <meta name="generator" content="WordPress 6.9.4"> |
Фильтр the_generator |
| Фиды RSS и Atom | Строка вроде <generator>https://wordpress.org/?v=6.9.4</generator> |
Тоже фильтр the_generator |
| URL файлов CSS и JavaScript | Параметр ?ver=, например style.min.css?ver=6.9.4 |
Фильтры style_loader_src и script_loader_src |
| HTTP-заголовки | X-Powered-By: PHP/8.3.x (версия PHP, а не WordPress) |
expose_php в php.ini |
readme.html |
Сведения о том, что используется WordPress (номера версии в нынешнем readme.html нет) | Закрыть доступ |
В данных сайта, которые возвращает /wp-json/ REST API (название, описание, URL, часовой пояс, пространства имён и т. д.), версии WordPress нет. Урезать вывод REST API ради скрытия версии не нужно.
Шаг 1. Проверьте, что отображается сейчас
Подставьте URL своего сайта и выполните команды на своём компьютере или на сервере. Если вы используете плагины кеширования или CDN, после изменений сначала очистите кеш, а затем проверяйте.
# Тег generator в HTML
curl -s https://example.com/ | grep -i 'name="generator"'
# generator в фиде
curl -s https://example.com/feed/ | grep -i '<generator>'
# Список значений ver= у CSS и JS
curl -s https://example.com/ | grep -oE 'ver=[0-9][0-9.]*' | sort | uniq -c
# Заголовок HTTP X-Powered-By
curl -sI https://example.com/ | grep -i 'x-powered-by'
# Доступен ли readme.html (200 — доступен)
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html
Если в списке значений ver= есть то же значение, что показано в админ-панели в разделе «Консоль» (Dashboard) → «Обновления» (Updates) как версия WordPress, то по этим CSS и JS версию WordPress можно определить. Если ядро WordPress или тема подключают CSS и JS без указания версии, в ver= попадает версия WordPress.
Шаг 2. Решите, куда поместить код
Код из этой статьи размещается в одном из двух мест.
- mu-plugin (рекомендуется): если положить PHP-файл в папку
wp-content/mu-plugins/(создайте её, если нет), он загружается без активации. Эффект сохранится и при смене темы functions.phpдочерней темы: если писать вfunctions.phpродительской темы, изменения пропадут при её обновлении
Если вы выбираете mu-plugin, соберите код следующего шага в один файл и сохраните его с именем вроде wp-content/mu-plugins/hide-wp-version.php.
Шаг 3. Скройте версию в теге generator и в ver=
<?php
/**
* Plugin Name: Hide WordPress Version
* Description: скрывает версию WordPress в теге generator и в ver= у CSS и JS.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Очищаем <meta name="generator"> в HTML и <generator> в фиде.
add_filter( 'the_generator', '__return_empty_string' );
/**
* Заменяем ver= у CSS и JS другим значением, только если оно совпадает с версией WordPress.
* Параметр не удаляется, а заменяется, поэтому после обновления WordPress кеш браузера обновляется.
*/
function wpdr_replace_wp_version_query( $src ) {
if ( ! is_string( $src ) || '' === $src ) {
return $src;
}
$query = wp_parse_url( $src, PHP_URL_QUERY );
if ( empty( $query ) ) {
return $src;
}
parse_str( $query, $args );
$wp_version = get_bloginfo( 'version' );
if ( isset( $args['ver'] ) && $args['ver'] === $wp_version ) {
$src = add_query_arg( 'ver', substr( wp_hash( $wp_version ), 0, 10 ), $src );
}
return $src;
}
add_filter( 'style_loader_src', 'wpdr_replace_wp_version_query', 20 );
add_filter( 'script_loader_src', 'wpdr_replace_wp_version_query', 20 );
Основные моменты.
- Фильтр
the_generatorдействует и на тег generator в HTML, и на generator в фидах.remove_action( 'wp_head', 'wp_generator' );убирает только тег в HTML, а на фиды не влияет - Если убрать
?ver=целиком, после обновления плагинов или тем браузер может продолжить использовать старые CSS и JS. Код выше заменяет значение на другую строку, полученную из версии, только если оно совпадает с версией WordPress. После обновления WordPress значение меняется, поэтому кеш обновляется - Значения
ver=, в которых плагины и темы указывают собственные номера версий, не меняются
После сохранения проверьте командами из шага 1, что generator не выводится, а в списке ver= не осталось версии WordPress. Если вы используете плагины кеширования, сначала очистите кеш.
Шаг 4. Отключите заголовок X-Powered-By
Заголовок X-Powered-By добавляет не WordPress, а PHP, и по нему видна версия PHP. Чтобы отключить его, в файле настроек PHP (php.ini) установите expose_php в Off. Эту настройку можно менять только в php.ini.
expose_php = Off
Пример для VPS с Ubuntu и PHP-FPM (8.3 замените версией PHP, которую вы используете).
# Проверить текущую настройку
grep -n '^expose_php' /etc/php/8.3/fpm/php.ini
# После изменения перезапустить PHP-FPM
sudo systemctl restart php8.3-fpm
В php.ini из пакетов Ubuntu по умолчанию уже стоит expose_php = Off. Если заголовок всё же выводится, проверьте, не используется ли другой php.ini. На арендованных хостингах эту настройку иногда можно менять в параметрах PHP в админ-панели, а иногда нельзя.
Если php.ini изменить нельзя, заголовок можно убрать и кодом WordPress. Но send_headers — хук, срабатывающий, когда WordPress выводит страницы публичной части сайта, поэтому на админ-панель и страницу входа он не действует.
add_action( 'send_headers', function () {
header_remove( 'X-Powered-By' );
} );
Шаг 5. Закройте доступ к readme.html и license.txt
readme.html и license.txt — файлы ядра WordPress. В нынешнем readme.html номера версии нет, но по нему видно, что используется WordPress.
Даже если их удалить, после обновления ядра WordPress они вернутся. Закрыть доступ на веб-сервере проще, чем удалять.
Для Apache (.htaccess)
Добавьте в .htaccess в папке WordPress. Между # BEGIN WordPress и # END WordPress WordPress переписывает содержимое сам, поэтому пишите за пределами этого блока. Это синтаксис Apache 2.4 (Order и Deny from all — старая запись Apache 2.2).
<FilesMatch "^(readme\.html|license\.txt)$">
Require all denied
</FilesMatch>
Для Nginx
Добавьте в блок server сайта, проверьте конфигурацию и перезагрузите её.
location ~* ^/(readme\.html|license\.txt)$ {
deny all;
}
sudo nginx -t && sudo systemctl reload nginx
После добавления выполните curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html и убедитесь, что возвращается 403.
Что скрытие не предотвращает
- Содержимое файлов CSS и JS WordPress немного отличается от версии к версии, поэтому, скачав файлы и сравнив их, версию можно угадать
- По
readme.txtиver=плагинов и тем иногда видны версии плагинов. Чаще атакуют уязвимости плагинов, а не ядра - Тем, кто может войти в админ-панель, версия по-прежнему показывается
Поэтому наряду со скрытием версии обновляйте ядро, плагины и темы, удаляйте неиспользуемые плагины, отключайте редактирование файлов в админ-панели и т. п.
Итоги
- Версия видна главным образом в generator в HTML и фидах и в
?ver=у CSS и JS. В/wp-json/REST API версии WordPress нет add_filter( 'the_generator', '__return_empty_string' );убирает generator и в HTML, и в фидах?ver=лучше не убирать, а заменять только значение, совпадающее с версией WordPress: тогда не нарушится обновление кешаX-Powered-Byотключается директивойexpose_php = Offв php.inireadme.htmlпосле удаления возвращается при обновлении, поэтому закройте доступ к нему на веб-сервере- Скрытие версии — вспомогательная мера, а самое важное — продолжать обновления
Похожие статьи:
- Настройка заголовков безопасности WordPress: .htaccess, Nginx, functions.php
- Как ограничить доступ к REST API в WordPress
- Отключение редактора файлов тем и плагинов в WordPress: DISALLOW_FILE_EDIT
Есть вопросы по WordPress? Издатель сайта находится в Японии и отвечает по-японски. Связаться (по-японски)