Перейти к содержимому

Файлы ядра WordPress генерируют ошибки при прямом открытии

Предупреждение Весь домен Безопасность

Общие инструкции. Откройте эту статью из отчёта PageCheck, чтобы увидеть её с адресом вашего сайта и правилами для его веб-сервера.

Что это такое

Некоторые файлы ядра WordPress, например wp-settings.php и файлы в wp-includes/, предназначены только для загрузки самим WordPress. Открытые напрямую в браузере, они выполняются и останавливаются с ошибкой PHP.

Что не так

Каждый раз, когда открывают один из этих файлов ядра, он генерирует ошибку. Если вывод ошибок включён, ошибка появляется и на странице с полным путём к папке сайта на сервере, и это показывает злоумышленникам, как устроен сервер.

Почему это нужно исправить: любой — боты или кто-то со злым умыслом — может открывать эти файлы снова и снова. Каждый запрос запускает PHP и записывает ещё одну ошибку в журнал сервера, поэтому журналы можно намеренно раздувать: они заполняют диск и прячут важные ошибки. Каждый ответ к тому же подтверждает, что сайт работает на WordPress.

Как исправить

1. Скройте ошибки PHP на рабочем сайте. Ошибки должны попадать в закрытый журнал, а не на страницу. В панели хостинга установите display_errors в Off:

  • Plesk: Websites & Domains → PHP Settings → display_errors выключено.
  • cPanel: MultiPHP INI Editor → display_errors Disabled.

В wp-config.php оставьте отладку включённой, но направляйте каждую ошибку только в файл журнала вне публичной папки сайта, чтобы ничего не попадало на страницу и никто не мог скачать журнал:

wp-config.php

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', '/path/outside/the/web/root/logs/wp-debug.log' );
@ini_set( 'display_errors', '0' );

Эти строки не действуют на файлы, которые открывает эта проверка: открытые напрямую, они останавливаются раньше, чем WordPress прочитает wp-config.php, поэтому их ошибки скрывает настройка хостинга выше. Настройте ротацию журнала (например, ежедневно, храня несколько недель): с включённой отладкой он собирает и уведомления и может быстро расти.

2. Закройте файлы ядра WordPress для прямых запросов. Используйте правила для своего веб-сервера (хостинг подскажет, какой он):

Apache или LiteSpeed: в файле .htaccess в главной папке сайта, над строкой «# BEGIN WordPress»

# BEGIN Block WordPress internal files
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/(?!ms-files\.php$)[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
<Files "wp-settings.php">
    Require all denied
</Files>
# END Block WordPress internal files

nginx: в блоке server сайта, над блоком, который обрабатывает файлы .php

location ~* ^/wp-admin/includes/ { deny all; }
location ~* ^/wp-includes/(?!ms-files\.php$)[^/]+\.php$ { deny all; }
location ~* ^/wp-includes/js/tinymce/langs/.+\.php$ { deny all; }
location ~* ^/wp-includes/theme-compat/ { deny all; }
location = /wp-settings.php { deny all; }

Это правила из руководства WordPress.org по усилению защиты с одним изменением: они оставляют открытым wp-includes/ms-files.php. Сети WordPress Multisite, созданные до WordPress 3.5, отдают загруженные файлы именно через этот один файл, а совет руководства для Multisite — убрать всю строку для wp-includes/*.php — снова открыл бы все остальные файлы в этой папке. На обычном сайте файл отвечает только «Multisite support not enabled». Если WordPress в подпапке, укажите эту папку в RewriteBase и в путях nginx.

3. Проверьте. Откройте https://example.com/wp-includes/theme-compat/embed.php: теперь адрес должен отвечать «Forbidden» (403) без текста ошибки. Откройте несколько страниц сайта и админку, чтобы убедиться, что они работают, затем запустите эту проверку снова.

Stop WordPress's core PHP files on my site from running and generating errors when opened directly.
Why it matters: anyone (bots included) can request these core files repeatedly, and every request writes a PHP error to the server log, so the logs can be bloated on purpose.

Steps:
1. Turn display_errors off for the live site (hosting PHP settings or php.ini). In wp-config.php keep WP_DEBUG true, set WP_DEBUG_DISPLAY false, and point WP_DEBUG_LOG to a file outside the web root (not wp-content/debug.log), with log rotation. Do not set WP_DEBUG to false.
2. Deny direct HTTP requests to wp-admin/includes/, wp-includes/*.php, wp-includes/js/tinymce/langs/*.php, wp-includes/theme-compat/ and wp-settings.php — WordPress.org's hardening rules in .htaccess on Apache/LiteSpeed (above # BEGIN WordPress), or deny location blocks placed before the PHP handler on nginx. Exempt only wp-includes/ms-files.php (Multisite networks from before WordPress 3.5 serve uploads through it): use ^wp-includes/(?!ms-files\.php$)[^/]+\.php$ rather than dropping the wp-includes/*.php rule.
3. Verify those addresses answer 403 with no error text, and that the site, the admin area, the block editor and uploads still work.
Tell me exactly which files you changed.

Resources:
- Hardening WordPress, securing wp-includes (WordPress.org): https://developer.wordpress.org/advanced-administration/security/hardening/#securing-wp-includes
- Debugging in WordPress (WordPress.org): https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/
- display_errors (PHP manual): https://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors

Проверьте свой сайт, чтобы узнать, есть ли у него эта проблема. Проверить сайт