Błąd 403 Forbidden oznacza, że serwer zrozumiał żądanie, ale odmawia dostępu do zasobu. W odróżnieniu od błędu 401 ponowne zalogowanie zwykle nic nie zmienia, bo blokada wynika z konfiguracji: uprawnień plików, reguł serwera albo zabezpieczeń, które uznały żądanie za podejrzane. W praktyce największą trudnością jest ustalenie, która warstwa zwraca błąd, bo 403 może pochodzić z serwera, aplikacji, wtyczki bezpieczeństwa albo CDN. W tym wpisie pokazuję, jak to ustalam i jak naprawiam najczęstsze przyczyny.
Dlaczego dostęp został zabroniony
| Przyczyna | Typowa sytuacja | Gdzie ją widać |
|---|---|---|
| uprawnienia lub właściciel plików | po przeniesieniu strony pliki należą do innego użytkownika albo katalog ma uprawnienia bez prawa wykonania | log błędów serwera |
| brak pliku startowego w katalogu | w katalogu nie ma index.php ani index.html, a listowanie plików jest wyłączone | log błędów Apache z komunikatem o zabronionym listowaniu |
reguły w .htaccess lub Nginx | Require all denied, deny all, ograniczenie dostępu do wybranych adresów IP | log błędów serwera, komunikat o odmowie w konfiguracji |
| zapora aplikacji (WAF) | ModSecurity na hostingu, reguła w Cloudflare, wtyczka bezpieczeństwa w WordPressie | log zapory, panel Cloudflare, dziennik wtyczki |
| blokada geograficzna lub po adresie IP | zablokowany kraj, adres biura po zmianie operatora, adres serwerów zewnętrznej usługi | reguły zapory i CDN |
| ochrona przed hotlinkowaniem | grafiki nie ładują się na innych stronach albo w aplikacji, bo reguła sprawdza nagłówek Referer | reguły w .htaccess lub CDN |
Jak diagnozuję i naprawiam błąd 403
1. Ustalam, która warstwa zwraca błąd
Najpierw sprawdzam nagłówki odpowiedzi, bo zwykle zdradzają, kto odmówił dostępu:
curl -I https://example.pl/wp-admin/
curl -I -A "Mozilla/5.0" https://example.pl/wp-admin/
Nagłówki server: cloudflare i cf-ray wskazują, że blokuje CDN, a nie serwer. Jeśli wynik różni się w zależności od
nagłówka User-Agent, blokadę nałożyła zapora, która filtruje boty i narzędzia. Strona błędu też bywa podpowiedzią: wtyczki
bezpieczeństwa i ModSecurity mają własne, rozpoznawalne komunikaty.
2. Czytam log serwera i zapory
W logu błędów Apache szukam komunikatów o odmowie dostępu w konfiguracji albo o zabronionym listowaniu katalogu. Na Nginx komunikat
access forbidden by rule wskazuje konkretną regułę deny. Jeśli hosting używa ModSecurity, w jego logu znajduję
identyfikator reguły, która zablokowała żądanie. Na tej podstawie wyłączam tylko tę jedną regułę dla konkretnego adresu, a nie całą zaporę.
Jak przeszukiwać logi i odróżniać ruch ludzi od botów, pokazuje analiza
logów serwera.
3. Poprawiam uprawnienia i właściciela plików
Po migracji strony najczęściej poprawiam uprawnienia tak, żeby katalogi miały 755, a pliki 644, i ustawiam właściciela, z którego działa serwer:
find /var/www/example.pl -type d -exec chmod 755 {} \;
find /var/www/example.pl -type f -exec chmod 644 {} \;
chown -R www-data:www-data /var/www/example.pl
Na hostingu współdzielonym bez dostępu do konsoli zmieniam uprawnienia przez klienta SFTP. Wystarczy w tym celu połączyć się z serwerem przez SFTP i zmienić atrybuty plików w menu klienta. Nigdy nie ustawiam uprawnień 777, bo usuwa to błąd 403, ale otwiera pliki do zapisu dla każdego procesu na serwerze.
4. Sprawdzam reguły w konfiguracji serwera
Zmieniam nazwę pliku .htaccess i sprawdzam stronę. Jeśli błąd znika, przywracam reguły po kolei, aż znajdę tę, która blokuje
dostęp. Najczęściej jest to ograniczenie dostępu do panelu po adresie IP, które przestało działać po zmianie adresu, albo zbyt szeroka
reguła blokująca pliki. Poprawne wzorce takich reguł stosuję w pliku .htaccess,
a reguły zapory w CDN sprawdzam razem z resztą, którą obejmuje konfiguracja CDN.
Błąd 403 a Googlebot
Najgroźniejszy dla widoczności jest błąd 403 zwracany tylko robotom. Zdarza się to po włączeniu agresywnej ochrony przed botami albo blokady całych krajów w zaporze. Strona działa normalnie w przeglądarce, a Googlebot dostaje odmowę i z czasem usuwa adresy z indeksu. Dlatego po każdej zmianie reguł zapory sprawdzam stronę w narzędziu do sprawdzania adresów URL w Search Console i upewniam się, że zweryfikowane roboty wyszukiwarek są wyłączone z blokad. Jednocześnie panel administracyjny i strony logowania powinny być chronione, a sposób, w jaki łączę zaporę z limitami prób logowania, pokazuje ochrona przed atakami brute force.
Pozostałe błędy HTTP
Każdy kod błędu wskazuje na inną warstwę, więc diagnozę zaczynam od innego miejsca: