Jak zabezpieczyć wp-config.php

Spis treści

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ą.

< Powrót

Zapisz się do newslettera


Zadzwoń Napisz