Przejdź do treści

Pliki rdzenia WordPressa generują błędy przy bezpośrednim otwarciu

Ostrzeżenie Cała domena Bezpieczeństwo

Ogólne instrukcje. Otwórz ten artykuł z raportu PageCheck, aby zobaczyć go wypełnionego adresem Twojej witryny i regułami dla jej serwera WWW.

Co to jest

Niektóre pliki rdzenia WordPressa, takie jak wp-settings.php i pliki w wp-includes/, mają być wczytywane tylko przez sam WordPress. Otwarte bezpośrednio w przeglądarce uruchamiają się i kończą błędem PHP.

Co jest nie tak

Za każdym razem, gdy ktoś otworzy jeden z tych plików rdzenia, generuje on błąd. Jeśli wyświetlanie błędów jest włączone, błąd pojawia się też na stronie z pełną ścieżką folderu witryny na serwerze, co mówi atakującym, jak zbudowany jest serwer.

Dlaczego trzeba to naprawić: każdy – boty albo ktoś o złych zamiarach – może otwierać te pliki raz po raz. Każde żądanie uruchamia PHP i zapisuje kolejny błąd w logu serwera, więc logi można celowo zapychać: zajmują dysk i zasypują błędy, które są ważne. Każda odpowiedź potwierdza też, że witryna działa na WordPressie.

Jak naprawić

1. Ukryj błędy PHP na działającej witrynie. Błędy powinny trafiać do prywatnego logu, nigdy na stronę. W panelu hostingu ustaw display_errors na Off:

  • Plesk: Websites & Domains → PHP Settings → display_errors wyłączone.
  • cPanel: MultiPHP INI Editor → display_errors Disabled.

W wp-config.php zostaw debugowanie włączone, ale kieruj każdy błąd tylko do pliku logu poza publicznym folderem witryny, aby nic nie trafiało na stronę i nikt nie mógł pobrać logu:

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' );

Te wiersze nie obejmują plików, które otwiera ten test: otwarte bezpośrednio kończą działanie, zanim WordPress wczyta wp-config.php, więc ich błędy ukrywa powyższe ustawienie hostingu. Rotuj log (na przykład codziennie, przechowując kilka tygodni): przy włączonym debugowaniu zbiera też powiadomienia i może szybko rosnąć.

2. Zamknij pliki rdzenia WordPressa dla bezpośrednich żądań. Użyj reguł dla swojego serwera WWW (Twój hosting powie Ci, który to):

Apache lub LiteSpeed: w pliku .htaccess w głównym folderze witryny, nad wierszem „# 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: w bloku server witryny, nad blokiem obsługującym pliki .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; }

To reguły z przewodnika po zabezpieczaniu WordPressa z WordPress.org, z jedną zmianą: zostawiają otwarty plik wp-includes/ms-files.php. Sieci WordPress Multisite utworzone przed WordPressem 3.5 udostępniają przesłane pliki właśnie przez ten jeden plik, a rada przewodnika dla Multisite – pominąć cały wiersz dla wp-includes/*.php – otworzyłaby z powrotem wszystkie pozostałe pliki w tym folderze. Na pojedynczej witrynie plik odpowiada tylko „Multisite support not enabled”. Jeśli WordPress jest w podfolderze, wpisz ten folder w RewriteBase i w ścieżki nginx.

3. Sprawdź. Otwórz https://example.com/wp-includes/theme-compat/embed.php: adres powinien teraz odpowiadać „Forbidden” (403) bez treści błędu. Otwórz kilka stron witryny i panel administracyjny, aby sprawdzić, że nadal działają, a potem uruchom ten test ponownie.

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

Sprawdź swoją stronę, aby zobaczyć, czy ma ten problem. Sprawdź stronę