- Co dokładnie chronisz i dlaczego to ma znaczenie
- Jakie dane zawiera wp-config.php
- Jakie zagrożenia eliminujesz
- Typowe błędy, których unikniesz
- Uprawnienia, właściciel i położenie pliku
- Ustal poprawnego właściciela i grupę
- Ustaw najwęższe sensowne prawa dostępu
- Atrybut „tylko do odczytu” i tryb immutable
- Przenieś plik poza katalog publiczny
- Specyfika środowisk współdzielonych i różne handlery PHP
- Blokowanie dostępu na poziomie serwera WWW
- Apache: reguły w .htaccess lub konfiguracji vhost
- Nginx: blokada przez location
- Testowanie reguł i szybka weryfikacja
- Edge cases: cache, proxy i nietypowe mapowania
- Zarządzanie sekretami i konfiguracją WordPressa
- Najpierw minimalizuj skutki wycieku: mocne hasła i mniejsze uprawnienia DB
- Klucze i sole SALT: generowanie i rotacja
- Środowiska i .env: lepsza separacja sekretów
- Wyłączenie wbudowanego edytora i modyfikacji z panelu
- Debug i błędy: nic na ekran w produkcji
- Prefix tabel i twarda konfiguracja
- Kopie zapasowe, monitoring i automatyzacja bezpieczeństwa
- Strategia backup i bezpieczne przechowywanie
- Monitoring integralności plików
- Wersjonowanie bez sekretów i kontrola dostępu
- Alerty i polityki operacyjne
- Checklisty na start i po migracji
- Instrukcje dla popularnych paneli
- Najczęstsze problemy i ich diagnoza
- Praktyczne przykłady i gotowe kroki
- Minimalny, szybki hardening w 10 minut
- Twardy hardening dla środowisk o wyższym ryzyku
- Sprawdzenie po każdym wdrożeniu
- Gdy masz tylko panel hostingowy (bez SSH)
- Bezpieczne logowanie błędów
- Słowa końcowe o kulturze bezpieczeństwa
Plik wp-config.php to serce konfiguracji WordPressa: zawiera połączenie z bazą, klucze kryptograficzne i ustawienia wpływające na bezpieczeństwo, wydajność i stabilność. Jeśli wpadnie w niepowołane ręce, atakujący zyska dostęp do danych i możliwość przejęcia witryny. Poniżej znajdziesz praktyczny, krok‑po‑kroku przewodnik, jak ograniczyć ryzyko wycieku, zredukować powierzchnię ataku i przygotować się na szybkie przywrócenie działania po incydencie.
Co dokładnie chronisz i dlaczego to ma znaczenie
Jakie dane zawiera wp-config.php
Plik wp-config.php przechowuje: nazwę bazy, użytkownika, hasło, host i prefix tabel, a także klucze i sól bezpieczeństwa WordPressa. Dodatkowo bywa uzupełniany o stałe kontrolujące aktualizacje, debug, cache czy integracje. Każdy wpis w tym pliku może zmieniać zachowanie witryny, a część z nich to dane wrażliwe. Dlatego chronisz zarówno poufność (żeby treść nie „wyciekła”), jak i integralność (żeby nikt nie zmienił wartości bez autoryzacji).
Jakie zagrożenia eliminujesz
- Nieautoryzowany odczyt: umożliwia poznanie danych do bazy, kluczy i wewnętrznej struktury środowiska.
- Nieautoryzowana modyfikacja: pozwala podmienić wartości i uzyskać code execution, wstrzyknąć backdoora lub wyłączyć zabezpieczenia.
- Eksfiltracja przez błąd konfiguracji serwera www lub wtyczki pozwalającej na przeglądanie plików.
Typowe błędy, których unikniesz
- Domyślne lub zbyt szerokie uprawnienia (np. 644 lub 664 na współdzielonym hostingu).
- Pozostawienie pliku w katalogu publicznym bez blokady na poziomie serwera.
- Trzymanie prawdziwych sekretów w repozytorium GIT.
- Wyświetlanie błędów PHP w produkcji, co może ujawnić ścieżki i fragmenty konfiguracji.
Uprawnienia, właściciel i położenie pliku
Ustal poprawnego właściciela i grupę
Na serwerach Linux witryna zwykle działa jako użytkownik procesu PHP (np. php-fpm) lub Apache. Plik powinien należeć do tego użytkownika, a grupa powinna uniemożliwiać odczyt innym stronom na współdzielonym hostingu. Sprawdź: ls -l wp-config.php. W razie potrzeby użyj chown użytkownik:grupa wp-config.php (w panelach hostingowych zrób to przez menedżera plików). Na Windowsie skorzystaj z NTFS i przypisz minimalne uprawnienia poprzez listy ACL w zakładce Security.
Ustaw najwęższe sensowne prawa dostępu
- Linux/Unix: zacznij od 400 (tylko właściciel czyta) lub 440 (właściciel i grupa czytają). W praktyce:
- chmod 400 wp-config.php — minimalizuje ryzyko odczytu przez innych.
- chmod 440 wp-config.php — gdy PHP działa jako inny użytkownik w tej samej grupie.
- chmod 600/640 — jeśli edytujesz plik częściej i chcesz także prawo zapisu dla właściciela.
Pamiętaj, by katalog nadrzędny nie pozwalał na zbędne przejście: 750 lub 710 zazwyczaj wystarcza.
- Windows: usuń dostęp Everyone, zostaw odczyt dla konta serwisu WWW i administratorów. Upewnij się, że konto publikujące nie ma zapisu w produkcji.
Atrybut „tylko do odczytu” i tryb immutable
Jeśli masz kontrolę nad VPS/dedykowanym serwerem na ext4/xfs, ustaw niezmienność: chattr +i wp-config.php. To blokuje modyfikacje nawet dla roota bez wcześniejszego usunięcia atrybutu (chattr -i). Stosuj świadomie: przed aktualizacjami i migracjami wyłącz atrybut, wykonaj zmiany, włącz ponownie. Na Windowsie zbliżony efekt da attrib +R, ale preferuj dokładne ACL.
Przenieś plik poza katalog publiczny
WordPress umożliwia umieszczenie wp-config.php o jeden poziom wyżej niż webroot (np. poza public_html). Mechanizm ładowania najpierw szuka pliku w katalogu nadrzędnym. Kroki:
- Skopiuj wp-config.php do katalogu powyżej publicznego (np. /home/user/wp-config.php).
- Usuń lub zarchiwizuj kopię w webroot (upewnij się, że ścieżki nie są twardo zakodowane).
- Przetestuj dostęp do witryny i panelu. Jeśli WordPress działa — przeniesienie jest skuteczne.
Dzięki temu nawet gdy serwer www źle przetworzy PHP, plik pozostaje poza zasięgiem żądań HTTP.
Specyfika środowisk współdzielonych i różne handlery PHP
W środowiskach z suPHP, FPM lub LSAPI właściciel pliku może różnić się od użytkownika serwera www. Dostosuj prawa do sytuacji — jeśli 400 powoduje błąd, spróbuj 440. Jeżeli używasz CRON lub WP-CLI pod innym kontem, możesz potrzebować 640. Unikaj 664/666. Kontroluj umask procesów wdrożeniowych, aby nie rozszerzała praw poza planowany zakres.
Blokowanie dostępu na poziomie serwera WWW
Apache: reguły w .htaccess lub konfiguracji vhost
Jeśli plik leży w docroot, zablokuj jego serwowanie. W .htaccess dodaj (wypisz znaki mniejsze/większe jako encje, jeśli edytujesz w HTML):
<Files wp-config.php>
Require all denied
</Files>
Starsze Apache 2.2: <Files wp-config.php> Order allow,deny Deny from all </Files>. Preferuj jednak reguły w konfiguracji vhost, bo są wydajniejsze i trudniej je nadpisać.
Nginx: blokada przez location
W bloku serwera dodaj regułę:
location ~* /wp-config.php {
deny all;
return 444;
}
Po zmianie: nginx -t i reload (systemctl reload nginx). Jeśli masz OLS/LSWS, użyj podobnej reguły w konfigu lub w .htaccess kompatybilnym dla LiteSpeed.
Testowanie reguł i szybka weryfikacja
- curl -I https://twoja-domena/wp-config.php — powinien zwrócić 403/444 lub nie serwować pliku.
- Sprawdź logi access/error, czy nie pojawiają się 200/206 dla wp-config.php.
- Przetestuj przekierowania i cache na CDN: upewnij się, że ruch nie omija Twojego serwera (np. przez nietypowy alias domeny).
Edge cases: cache, proxy i nietypowe mapowania
Gdy używasz reverse proxy lub WAF (np. Cloudflare), filtruj żądania do wp-config.php już na brzegu: ustaw reguły blokujące URL o tej nazwie. Zadbaj, by origin i wszystkie warstwy pośrednie nie ujawniały treści nawet w razie miss-configu. W katalogach wieloinstancyjnych (multisite, wiele witryn w jednym docroot) powiel zasady dla każdego vhost.
Zarządzanie sekretami i konfiguracją WordPressa
Najpierw minimalizuj skutki wycieku: mocne hasła i mniejsze uprawnienia DB
- Utwórz dedykowanego użytkownika bazy z minimalnymi prawami do swojej bazy (SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP — tylko gdy konieczne; w produkcji często wystarczy zestaw bez tworzenia struktur, jeśli nie instalujesz wtyczek bezpośrednio).
- Zmieniaj hasła cyklicznie i po każdej migracji środowiska. Nie używaj żadnego hasła ponownie.
- Ogranicz hosty, z których użytkownik DB może się łączyć (np. tylko localhost).
Klucze i sole SALT: generowanie i rotacja
Klucze AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY i odpowiadające im sole wzmacniają podpisy cookies i nonce. Wygeneruj nowe na https://api.wordpress.org/secret-key/1.1/salt/ i wklej do wp-config.php. Po incydencie zawsze rotuj klucze (wszyscy zostaną wylogowani). Automatyzacja: cron + skrypt rotujący w utrzymaniu, ale pamiętaj o oknie serwisowym.
Środowiska i .env: lepsza separacja sekretów
Zamiast umieszczać poświadczenia w repozytorium, przechowuj je w zmiennych środowiskowych lub plikach .env poza webroot. Biblioteka phpdotenv lub rozwiązania jak Bedrock upraszczają ten model. W wp-config.php odczytuj: getenv(’DB_NAME’), getenv(’DB_USER’) itd. Sekrety trzymaj w sejfach chmurowych (np. AWS Secrets Manager, GCP Secret Manager) i wstrzykuj na serwer podczas wdrożeń.
Wyłączenie wbudowanego edytora i modyfikacji z panelu
Dodaj w wp-config.php:
- define(’DISALLOW_FILE_EDIT’, true); — blokuje edytor motywów/wtyczek w kokpicie.
- define(’DISALLOW_FILE_MODS’, true); — blokuje instalację/aktualizacje z panelu (używaj, jeśli masz pipeline CI/CD).
To redukuje ryzyko nadużyć po uzyskaniu dostępu do konta administracyjnego.
Debug i błędy: nic na ekran w produkcji
- define(’WP_DEBUG’, false);
- ini_set(’display_errors’, 0); ini_set(’log_errors’, 1);
- Dzienniki trzymaj poza webroot z prawami 600/640, aby nie wyciekały przez HTTP.
Wyświetlenie błędów w przeglądarce może zdradzić ścieżki, wersje i fragmenty konfiguracji. W razie potrzeby udostępniaj logi tylko zespołowi operacyjnemu.
Prefix tabel i twarda konfiguracja
Zmień table_prefix z domyślnego wp_ na unikalny, co ogranicza skuteczność części automatycznych ataków. W połączeniu z cięciem uprawnień DB utrudnia to wykonanie niektórych payloadów SQL skierowanych w standardowe nazwy tabel.
Kopie zapasowe, monitoring i automatyzacja bezpieczeństwa
Strategia backup i bezpieczne przechowywanie
- Twórz kopie plików i bazy z szyfrowaniem po stronie źródła (np. gpg, age) lub na magazynie (SSE-KMS w chmurze). Klucze szyfrujące trzymaj osobno.
- Backupy nie powinny być dostępne przez HTTP. Upewnij się, że katalogi backupów nie leżą w docroot lub są blokowane na poziomie serwera.
- Testuj odtwarzanie co najmniej kwartalnie. Martwy backup to brak backupu.
Monitoring integralności plików
Wdróż monitor zmian na wp-config.php:
- Narzędzia WordPress (np. wtyczki typu skaner integralności) z alertami mail/Slack.
- Systemowe: inotify/auditd (Linux) do logowania zdarzeń WRITE/CHMOD/CHOWN na tym pliku.
- Prosty skrypt sprawdzający hash (sha256sum) co kilka minut i wysyłający alert przy rozbieżności.
Połączenie monitoringu z atrybutem immutable zwiększa szansę, że wykryjesz i powstrzymasz nieautoryzowaną modyfikację szybko.
Wersjonowanie bez sekretów i kontrola dostępu
- Nie commituj prawdziwego wp-config.php. Trzymaj szablon wp-config.sample.php bez sekretów i z instrukcją, jak wstrzyknąć je w środowisku.
- Dodaj do .gitignore wpis dla wp-config.php i plików .env.
- W pipeline CI/CD ustaw zmienne środowiskowe i wdrażaj przez bezpieczne kanały (SSH z kluczami, agent po stronie serwera, brak haseł w logach).
Alerty i polityki operacyjne
- Skonfiguruj powiadomienia o zmianach praw dostępu i właściciela pliku.
- Ustal procedurę incydentową: rotacja haseł DB, kluczy SALT, przywrócenie z kopii i przegląd logów.
- Ogranicz ludzi i systemy mające dostęp do tajemnic (zasada najmniejszych uprawnień).
Checklisty na start i po migracji
Nowa instalacja:
- Wygeneruj unikalne klucze i sole.
- Utwórz użytkownika DB z ograniczonymi prawami i silnym hasłem.
- Ustaw prawa: chmod 400/440, poprawny właściciel i grupa.
- Przenieś wp-config.php poza webroot, jeśli to możliwe.
- Zablokuj dostęp w serwerze WWW (Apache/Nginx).
- Wyłącz edytor plików i modyfikacje z panelu, jeśli masz pipeline.
- Skonfiguruj monitoring i backupy.
Po migracji/aktualizacji:
- Sprawdź, czy prawa i właściciel nie uległy rozszerzeniu.
- Potwierdź działanie blokad w serwerze WWW i CDN.
- Zweryfikuj, czy logi nie trafiają do katalogów publicznych.
- Opcjonalnie ustaw ponownie atrybut immutable.
Instrukcje dla popularnych paneli
cPanel / DirectAdmin:
- File Manager: kliknij wp-config.php, wybierz Permissions i ustaw 400/440 (czasem 440 wymagane).
- Edytor .htaccess: dodaj regułę blokującą dostęp.
- MySQL® Databases: utwórz użytkownika DB, przypisz tylko niezbędne prawa do konkretnej bazy.
Plesk:
- Hosting Settings: wyłącz „Scripts and FastCGI” dla katalogów backupów.
- File Permissions: ustaw odczyt tylko dla konta serwisu i właściciela subskrypcji.
Najczęstsze problemy i ich diagnoza
- HTTP 500 po zmianie praw — proces PHP nie ma dostępu. Zmień 400 → 440 lub skoryguj grupę.
- Aktualizator nie może zapisać — jeśli to świadoma polityka, aktualizuj przez CI/CD; jeśli nie, użyj 600 tymczasowo i przywróć 400 po operacji.
- Reguły .htaccess ignorowane — sprawdź AllowOverride w konfiguracji Apache lub włącz obsługę .htaccess w hostingu.
- Nginx dalej serwuje — upewnij się, że reguła location znajduje się przed bardziej ogólnymi dopasowaniami i wykonaj reload.
Praktyczne przykłady i gotowe kroki
Minimalny, szybki hardening w 10 minut
- Ustaw właściciela i grupę pliku zgodnie z użytkownikiem PHP/Apache.
- chmod 400 wp-config.php (lub 440 w zależności od konfiguracji).
- Dodaj blokadę w serwerze WWW:
- Apache: <Files wp-config.php> Require all denied </Files>
- Nginx: location ~* /wp-config.php { deny all; return 444; }
- Wyłącz edytor plików w panelu: define(’DISALLOW_FILE_EDIT’, true);
- Zweryfikuj curl -I /wp-config.php → 403/444.
Twardy hardening dla środowisk o wyższym ryzyku
- Przenieś wp-config.php poza webroot i ustaw katalog nadrzędny na 710.
- Włącz atrybut immutable (chattr +i), dokumentując proces jego czasowego wyłączania.
- Wyprowadź sekrety do zmiennych środowiskowych / sejfu, w pliku trzymaj jedynie odczyt getenv().
- Wdróż rotację kluczy SALT co ustalony okres i po incydencie.
- Uruchom auditd do monitorowania CHMOD/CHOWN/WRITE na pliku.
- Backupy szyfruj i przechowuj w innej strefie/regionie, testuj odtwarzanie.
Sprawdzenie po każdym wdrożeniu
- ls -l wp-config.php — czy prawa i właściciel są zgodne z polityką.
- grep -n „DB_PASSWORD” wp-config.php — upewnij się, że nie ma duplikatów/pozostałości.
- curl -I /wp-config.php — reguły blokujące wciąż działają.
- Logi serwera: brak odpowiedzi 200 dla wp-config.php.
Gdy masz tylko panel hostingowy (bez SSH)
- Zmień prawa w File Managerze na 400/440.
- Edytuj .htaccess i wklej regułę Files Deny.
- Utwórz osobnego użytkownika DB z nowym, silnym hasłem i zaktualizuj wp-config.php.
- Wyłącz edytor plików z panelu WordPress, dodając stałą przez File Manager.
Bezpieczne logowanie błędów
Jeśli włączasz logowanie, skieruj error_log do katalogu poza webroot i ustaw prawa 600. Nie przechowuj logów dłużej niż to konieczne. Rotuj pliki (logrotate) i włącz monitoring rozmiaru, by uniknąć zapchania dysku.
Słowa końcowe o kulturze bezpieczeństwa
Techniczne zabezpieczenia są skuteczne, gdy idą w parze z praktykami operacyjnymi: kontrolą zmian, minimalnymi dostępami, szybką reakcją na alerty i regularnymi przeglądami. Dla krytycznych witryn formalizuj proces: checklisty, przeglądy kwartalne, audyty konfiguracyjne i testy odtwarzania. Nawet najlepsze ustawienia nie pomogą, jeśli ktoś pozostawi przypadkową kopię pliku w katalogu publicznym pod inną nazwą.