Articles

WordPress Error Fix: „Call to undefined function get_header()”

♦ Posted by Jeff Starr in PHP, Security
January 11, 2019

Obserwuję duży wzrost ataków botów celujących bezpośrednio w pliki motywów. Najpierw dostają adres URL do twojego katalogu motywu. Istnieje wiele sposobów na zdobycie tej informacji przez bota. Na przykład większość motywów zawiera zasoby takie jak pliki CSS i JavaScript, a link zawiera pełny adres URL. Tak więc po zdobyciu adresu URL motywu, złe boty będą bezpośrednio pytać o dobrze znane pliki szablonów motywów, takie jak index.php i header.php. Bezpośrednie żądanie plików szablonów może ujawnić możliwe luki w zabezpieczeniach, co najwyraźniej jest coraz bardziej popularnym wektorem ataku. Wywołuje to również błędy typu „Call to undefined function get_header()” (i podobne). Na szczęście istnieje łatwa poprawka.

Czy twoja witryna jest celem ataku?

Aby dowiedzieć się, czy twoja witryna jest atakowana bezpośrednimi żądaniami plików motywu, możesz sprawdzić logi dostępu/błędów swojej witryny. Oto kilka przykładów z moich własnych dzienników, które powinny pomóc pokazać, czego szukać:

Uwaga: W następujących wpisach dziennika wszystkie ścieżki do plików zostały zmienione na przykładowe adresy URL, aby uniemożliwić Google indeksowanie i zgłaszanie błędów. W rzeczywistych plikach dziennika, błędy zawierają ścieżki do plików, a nie adresy URL. P.S., najbardziej niedorzeczne jest to, że Googlebot indeksuje informacje o ścieżkach w postaci zwykłego tekstu, wewnątrz znaczników <pre>, nie mniej.
2018-12-30 17:54:07 ErrorAH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function get_header() in https://example.com/wp-content/themes/digwp/index.php:1Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/index.php on line 1'2018-12-30 12:53:55 ErrorAH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function get_header() in https://example.com/wp-content/themes/digwp/404.php:1Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/404.php on line 1'2018-12-30 12:53:55 ErrorAH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function esc_url() in https://example.com/wp-content/themes/digwp/header.php:8Stack trace: #0 {main} thrown in https://example.com/wp-content/themes/digwp/header.php on line 8'

Tak więc, jeśli twoja witryna jest celem ataków typu direct-template, zobaczysz mnóstwo tego typu błędów. W tych przykładach, żądania dotyczą index.php, 404.php i header.php. Z moich analiz, większość żądań szablonów są dla tych trzech plików, ale można również znaleźć je skanowania dla innych znanych plików WordPress, takich jak:

/archive.php/wp-includes/rss-functions.php ..various theme template files..various files in the WP Media Library

Podstawowo, każde bezpośrednie żądanie do rdzenia WordPress, motyw, lub plik wtyczki najprawdopodobniej wywoła błąd, chyba że odpowiednie środki są podejmowane wcześniej. Na przykład, później przyjrzymy się łatwemu sposobowi na zatrzymanie błędu „niezdefiniowanej funkcji”, co z kolei pomoże zachować cenne zasoby serwera i poprawić ogólne bezpieczeństwo witryny.

Zrozumienie błędu

Więc o co chodzi z fatalnymi błędami „wywołania niezdefiniowanej funkcji”? Dzieje się tak, ponieważ rdzeń WordPress nie jest ładowany dla bezpośrednio załadowanych plików szablonów.

Na przykład, jeśli zażądasz header.php bezpośrednio, wszelkie funkcje rdzenia, takie jak esc_url(), nie są dostępne, ponieważ plik jest żądany poza WordPress.

Co się stanie, jeśli nic nie zrobisz? Cóż, twój motyw może już zaimplementować podobną technikę, a może nie. Jakie jest ryzyko? W zależności od tego, jak zakodowany jest twój motyw, może być możliwe dla złych aktorów wykonanie kodu poza kontekstem, co może odsłonić potencjalne wektory ataku.

Jak naprawić

Najprostszym sposobem na zapobieżenie tego typu błędom jest po prostu wyjście ze skryptu, jeśli WordPress nie jest dostępny. Jest to starożytna, ale skuteczna technika PHP używana do zapobiegania bezpośredniemu dostępowi do plików:

<?php if (!defined('ABSPATH')) exit; ?>

Po prostu mówi: Jeśli stała ABSPATH nie jest zdefiniowana, to zakończ skrypt. Działa to, ponieważ ABSPATH jest zdefiniowana tylko wtedy, gdy WordPress jest załadowany. Więc kiedy zły bot przyjdzie i zacznie żądać twoich szablonów motywów, po prostu dostanie pustą stronę (pustą odpowiedź) z serwera.

Może widziałeś podobny kod podczas swoich podróży po WordPressie. Zapobieganie bezpośredniemu dostępowi do skryptu jest ważną częścią bezpieczeństwa PHP. Nie chcesz, aby napastnicy/boty uruchamiały skrypty bez kontekstu, gdy nie są autoryzowane, i tak dalej.

Przykład

Aby zaimplementować tę technikę, otwórz pliki motywów, które są celem ataku, i dołącz linię na górze pliku. Na przykład, wiele szablonów motywów zawiera nagłówek przed jakimkolwiek innym kodem, wygląda to tak:

<?php get_header(); ?>

Po dodaniu fragmentu „bez bezpośredniego dostępu”, będziesz miał coś takiego:

<?php if (!defined('ABSPATH')) exit;get_header(); ?>

Jakkolwiek zdecydujesz się sformatować kod jest w porządku, chodzi o włączenie linii ABSPATH przed wywołaniem jakichkolwiek innych funkcji.

Pro Tip: Chcesz zatrzymać więcej złych botów? Sprawdź moją darmową wtyczkę WordPress, Blackhole for Bad Bots, dostępną w WP Plugin Directory.

Bonus

Aby pójść dalej, możesz chronić poufne informacje o plikach, wyłączając widoki katalogów. Na przykład, jeśli odwiedzasz swój katalog macierzysty motywu w przeglądarce, co widzisz? Jeśli widoki katalogów są włączone, otrzymasz połączoną listę wszystkich plików. Nie jest to dobre. To, co powinieneś zobaczyć, to albo pusty biały ekran, albo jakaś inna odpowiedź serwera. Wiesz, aby pomóc utrzymać informacje o plikach bezpieczne i zabezpieczone.

Istnieje wiele sposobów, aby wyłączyć widoki katalogów. Sposób WordPressa polega na utworzeniu nowego (pustego) pliku index.php w dowolnym katalogu, który chcesz chronić.

Ważne! Tylko utwórz nowy plik index.php, jeśli jeden NIE istnieje już w katalogu. To znaczy, nie nadpisuj żadnych istniejących plików indeksu.

Następnie w index.php dodaj następujący kod:

<?php // Silence is golden.

Rdzeń WordPress używa tej techniki w różnych katalogach. Poprzez wyłączenie widoków otwartych katalogów, uniemożliwiamy atakującym uzyskanie informacji o tym, które pliki istnieją na serwerze. Tak więc przynosi to korzyści dla bezpieczeństwa i jest zalecaną praktyką dla wszystkich publicznych katalogów, chyba że masz to pokryte z .htaccess, lub może masz powód, aby zrobić inaczej i pozostawić widoki włączone dla konkretnego katalogu.

Myślenia końcowe

Proste techniki opisane w tym artykule są sprawdzonymi środkami bezpieczeństwa, które zapobiegną niebezpiecznemu wykonywaniu kodu i powstrzymają błędy od wypełniania twoich dzienników. Oznacza to lepszą wydajność i bezpieczeństwo dla Twojej witryny. Nawet jeśli nie doświadczasz błędów opisanych w tym artykule, ochrona plików motywów i wtyczek przed bezpośrednim dostępem jest dobra dla bezpieczeństwa.

Jeff Starr

O autorze
Jeff Starr = Projektant. Deweloper. Producent. Pisarz. Redaktor. Etc.

.