Zabezpieczanie strony: uprawnienia, nagłówki i wtyczki bezpieczeństwa
Moduł 7: Bezpieczeństwo · Czas czytania: 10 minut
Cel lekcji: Po tej lekcji będą Państwo potrafili zabezpieczyć stronę WordPress za pomocą uprawnień, ustawień i nagłówków bezpieczeństwa, a także ocenić wartość wtyczek bezpieczeństwa.
Kluczowe pojęcia: zabezpieczanie (hardening), uprawnienia do plików (644, 755), DISALLOW_FILE_EDIT, brak PHP w uploads, listowanie zawartości katalogów, ukrywanie wersji, X-Powered-By, nagłówki bezpieczeństwa, pliki kopii zapasowych i .git w katalogu strony, WAF na serwerze, WAF we wtyczce, skaner malware
Czym jest zabezpieczanie (hardening)
Zabezpieczanie (hardening) oznacza: takie skonfigurowanie strony, aby błąd lub luka mogły wyrządzić jak najmniej szkody. Nie zastępuje to aktualizacji ani silnych haseł (lekcja 7.2 i 7.3), ale zmniejsza skutki. Proszę to sobie wyobrazić jak dom: aktualizacje to zamki, zabezpieczanie to sprawienie, by włamywacz, który mimo wszystko dostał się do środka, nie dotarł do sejfu.
Uprawnienia do plików
Każdy plik i każdy katalog na serwerze ma uprawnienia: kto może czytać, zapisywać i wykonywać. Zapisuje się je jako trzy cyfry, dla właściciela, grupy i reszty świata. Wytyczna z dokumentacji WordPress:
| Co | Uprawnienia | Znaczenie |
|---|---|---|
| Katalogi | 755 | Właściciel może wszystko, inni mogą czytać i otwierać |
| Pliki | 644 | Właściciel może czytać i zapisywać, inni tylko czytać |
| wp-config.php | bardziej restrykcyjnie, np. 600 lub 640 | Czytać może tylko właściciel (i ewentualnie grupa serwera WWW) |
To, która wartość dla wp-config.php zadziała, zależy od sposobu, w jaki Państwa hosting uruchamia PHP: przy większości hostingu współdzielonego PHP działa jako Państwa własny użytkownik, wtedy wystarczy 600. Proszę spróbować i sprawdzić, czy strona nadal działa.
Nigdy 777. Oznacza to: każdy na serwerze może zapisywać. Instrukcja, która mówi „ustaw katalog na 777, jeśli przesyłanie plików nie działa”, rozwiązuje problem w niewłaściwy sposób. Przy dobrym hostingu nigdy nie jest to potrzebne.
Ustawienia w wp-config.php
Kilka linijek, które robią dużą różnicę (powyżej „to wszystko, zaprzestań edytowania”):
// Brak edycji plików z poziomu kokpitu (Wygląd > Edytor motywów i Wtyczki > Edytor wtyczek).
define( 'DISALLOW_FILE_EDIT', true );
// Komunikaty błędów nigdy na ekranie odwiedzających (lekcja 5.4).
define( 'WP_DEBUG', false );Dzięki DISALLOW_FILE_EDIT znika edytor, za pomocą którego w kokpicie można zmieniać pliki PHP motywów i wtyczek. Włamywacz, który przejmie konto administratora, nie może wtedy dwoma kliknięciami umieścić złośliwego kodu w Państwa motywie. Nadal można instalować wtyczki; jeśli chcą Państwo zabronić także i tego (na przykład przy stronie zarządzanej dla klienta), istnieje DISALLOW_FILE_MODS, ale wtedy przestają też działać aktualizacje z poziomu kokpitu.
Brak PHP w uploads, brak listowania katalogów
W katalogu wp-content/uploads powinny znajdować się obrazy i dokumenty, nigdy pliki PHP. Włamywacze, którzy dzięki luce mogą przesłać plik, próbują umieścić tam właśnie plik PHP i następnie go wywołać. Proszę to zablokować za pomocą pliku .htaccess w katalogu uploads (przy LiteSpeed i Apache):
<Files *.php>
Require all denied
</Files>Proszę też wyłączyć wyświetlanie zawartości katalogów. Bez pliku index.php lub index.html w katalogu niektóre serwery WWW pokazują listę wszystkich plików ("Index of /wp-content/uploads/2026/11"). To wystawa dla kogoś, kto szuka kopii zapasowych lub wrażliwych dokumentów. W pliku .htaccess katalogu strony:
Options -IndexesWielu dostawców hostingu ma to już domyślnie wyłączone. Zadanie z tej lekcji to sprawdza.
Żadnych pozostałości w katalogu strony
Wszystko w katalogu strony można wywołać przez sieć, z wyjątkiem tego, co serwer wykonuje jako PHP lub blokuje. Niebezpieczne są:
- kopie wp-config.php (
wp-config.php.bak,wp-config.old,wp-config.php~pozostawione przez edytor tekstu): zawierają hasło do bazy danych i są przesyłane jako zwykły tekst (lekcja 1.3); - kopie zapasowe typu
backup.zip,site.tar.gzlubdatabase.sqlw katalogu strony; - katalog
.gitpozostawiony przez programistę, dzięki któremu można pobrać cały Państwa kod (a czasem i hasła); - debug.log w wp-content (lekcja 5.4);
- stare pliki instalacyjne lub testowe, takie jak
info.phpzphpinfo().
Proszę przechowywać kopie zapasowe poza katalogiem strony lub poza serwerem i usuwać pozostałości.
Ukrywanie wersji: niewielka korzyść
WordPress domyślnie umieszcza w kodzie HTML:
<meta name="generator" content="WordPress 7.1.4" />i to samo w kanale RSS. Również PHP czasem ujawnia się w nagłówku: X-Powered-By: PHP/8.3.14. Ukrycie tego jest rozsądne, ale nie warto oczekiwać zbyt wiele: programy włamywaczy po prostu próbują wykorzystać lukę, niezależnie od pokazywanej wersji, a wersje często można też odczytać z ?ver= za skryptami. Ukrywanie to porządkowanie, nie zabezpieczenie. Strona, która ukrywa wersję, ale nie jest aktualizowana, jest równie podatna na ataki.
Można to zrobić w niewielkiej własnej wtyczce lub w pliku functions.php motywu potomnego:
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'the_generator', '__return_empty_string' );A nagłówek PHP, ustawiając expose_php = Off w ustawieniach PHP u Państwa dostawcy hostingu (przy DirectAdmin w Select PHP version, Options), lub za pomocą Header unset X-Powered-By w pliku .htaccess.
Nagłówki bezpieczeństwa
Za pomocą kilku nagłówków informują Państwo przeglądarkę, jak ma postępować ze stroną. Najważniejsze z nich:
| Nagłówek | Co robi |
|---|---|
Strict-Transport-Security | Tylko przez https (lekcja 3.1) |
X-Content-Type-Options: nosniff | Przeglądarka nie zgaduje, jakim typem pliku coś jest; zapobiega wykonaniu przesłanego „obrazka” jako skryptu |
X-Frame-Options: SAMEORIGIN lub Content-Security-Policy: frame-ancestors 'self' | Inne strony nie mogą pokazywać Państwa strony w ramce; zapobiega clickjackingowi (niewidoczny przycisk Państwa strony pod przyciskiem innej strony) |
Referrer-Policy: strict-origin-when-cross-origin | Przy kliknięciu prowadzącym do innej strony przekazywana jest tylko nazwa domeny, nie pełny adres |
Permissions-Policy | Wyłącza funkcje przeglądarki, których Państwa strona nie używa (kamera, mikrofon, lokalizacja) |
Content-Security-Policy | Określa dokładnie, z jakich źródeł mogą pochodzić skrypty i style. Potężne narzędzie, ale trudne do prawidłowego skonfigurowania przy WordPressie i wtyczkach; proszę zacząć od trybu Report-Only |
W pliku .htaccess (przy LiteSpeed i Apache):
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>Następnie proszę sprawdzić, czy wszystko działa: treści osadzone, przyciski płatności, widżet czatu. Narzędzia zewnętrzne, takie jak securityheaders.com i internet.nl, pokazują, co wysyła Państwa strona.
Wtyczki bezpieczeństwa, spojrzenie na trzeźwo
Istnieje wiele wtyczek bezpieczeństwa (na przykład Wordfence, Solid Security, All-In-One Security, Sucuri). Często łączą one: zaporę sieciową, skaner malware, zabezpieczenie logowania, uwierzytelnianie dwuskładnikowe, powiadomienia i listę zaleceń dotyczących zabezpieczeń. Przydatne, ale z ograniczeniami:
- Zapora sieciowa we wtyczce (WAF) uruchamia się dopiero, gdy działa PHP. Złośliwe żądanie musi najpierw przejść przez serwer WWW i PHP, zanim wtyczka je zobaczy. Luka w pliku PHP wywoływanym bezpośrednio lub atak znacząco obciążający samo PHP, nie zawsze zostaną zatrzymane. Zapora na serwerze (na przykład ModSecurity, Imunify360 lub zapora Państwa dostawcy hostingu) znajduje się wcześniej w łańcuchu i zatrzymuje więcej, bez obciążania Państwa strony obliczeniami. Proszę zapytać swojego dostawcę hostingu, co działa na serwerze.
- Skaner wykrywa po fakcie. Skaner malware informuje Państwa, że coś jest nie tak. To cenne, ale niczego nie zapobiega. A skaner na tym samym serwerze co zhakowana strona również może zostać zmieniony przez włamywacza.
- Nie zastępują aktualizacji. Wtyczka ze znaną luką pozostaje podatna, nawet z działającą obok wtyczką bezpieczeństwa. Niektóre usługi bezpieczeństwa oferują „wirtualne łatki”, które zatrzymują znane ataki do czasu wykonania aktualizacji; przydatne jako rozwiązanie tymczasowe, nie jako zamiennik.
- Same są wtyczką. Więcej kodu, więcej do aktualizowania, czasem same zawierają lukę. A dwie wtyczki bezpieczeństwa jednocześnie często się ze sobą kłócą.
- Kosztują moc obliczeniową, zwłaszcza skanery działające na Państwa własnym serwerze.
Rozsądny wybór: proszę najpierw sprawdzić, co już robi Państwa dostawca hostingu (zapora sieciowa, skanowanie malware, blokowanie prób logowania). Proszę uzupełnić to, czego brakuje, zwykle uwierzytelnianie dwuskładnikowe i ograniczenie liczby prób logowania. Rozbudowana wtyczka bezpieczeństwa jest szczególnie przydatna przy hostingu, który sam robi niewiele.
Podsumowanie
- Zabezpieczanie (hardening) ogranicza szkody wynikające z błędu lub luki; nie zastępuje aktualizacji i haseł.
- Katalogi 755, pliki 644, wp-config.php bardziej restrykcyjnie; nigdy 777.
- Proszę włączyć DISALLOW_FILE_EDIT, zablokować PHP w uploads, wyłączyć listowanie katalogów i usunąć kopie zapasowe, .git oraz debug.log z katalogu strony.
- Ukrywanie wersji to porządkowanie, nie zabezpieczenie; nagłówki bezpieczeństwa pomagają przeglądarce chronić Państwa odwiedzających.
- Zapora na serwerze zatrzymuje więcej niż wtyczka; wtyczki bezpieczeństwa są uzupełnieniem, nie zamiennikiem.
Quiz
Zadanie
Zadanie A7.4: Co Państwa strona pokazuje wszystkim? Proszę wpisać adres swojej strony. Program odczyta stronę główną i kanał RSS (/feed/) oraz sprawdzi: czy w znaczniku generatora kodu HTML i kanału nie ma wersji WordPressa, czy nagłówek X-Powered-By nie pokazuje wersji PHP oraz czy strona wysyła X-Content-Type-Options: nosniff, ochronę przed ramkami (X-Frame-Options lub frame-ancestors) i Referrer-Policy? Brak HSTS (lekcja 3.1) i Permissions-Policy jest dopuszczalny (pomarańczowy).
Zadanie A7.4b: Brak zbędnych plików w katalogu strony. Proszę udowodnić, że to Państwa strona (rekord TXT lub plik z kodem zadania). Program następnie sprawdzi krótką stałą listę: katalog /wp-content/uploads/ (brak listowania zawartości), /.git/HEAD, /wp-content/debug.log oraz kilka popularnych nazw kopii wp-config.php. Wynik jest dobry, jeśli żaden z nich nie zwraca treści (404 lub 403). Program niczego innego nie sprawdza i niczego nie zmienia.
Dalsza lektura
Te artykuły opisują kroki w panelach WebOké; w innych panelach działają one podobnie.
- Instrukcja DirectAdmin 11.5: Uprawnienia plików i katalogów (chmod)
- Instrukcja DirectAdmin 11.4: Pokazywanie i edycja ukrytych plików, takich jak .htaccess
- Instrukcja DirectAdmin 15.10: Zapora sieciowa aplikacji internetowych
- Instrukcja DirectAdmin 15.11: Imunify360: skanowanie strony w poszukiwaniu malware
- Blokowanie plików przez .htaccess, np. plugin-googlemap2-proxy.php
- Bezpieczeństwo PHP
- Zabezpieczanie WordPressa (developer.wordpress.org, w języku angielskim): https://developer.wordpress.org/advanced-administration/security/hardening/
- Nagłówki bezpieczeństwa (MDN, w języku angielskim): https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#security
