# expose_php i nagłówki Server: ukrywanie informacji o wersji

> expose_php, X-Powered-By i nagłówek Server: gdzie PHP i serwer WWW zdradzają wersję, jak to wyłączyć w php.ini, Nginx i Apache oraz jak sprawdzić efekt.

Źródło: https://phpsos.de/pl/blog/expose-php-versionsangaben/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**Krótko:** Dzięki `expose_php = Off` w php.ini znika nagłówek `X-Powered-By: PHP/…`. Do tego należą `server_tokens off;` w Nginx oraz `ServerTokens Prod` i `ServerSignature Off` w Apache. Nie czyni to żadnego serwera bezpieczniejszym, ale odbiera zautomatyzowanym skanom gotową listę wersji. Własny stan poprawek sprawdzają Państwo potem przez menedżer pakietów i procesy, a nie przez nagłówki.

## Wizytówka w każdej odpowiedzi

Kto po 21 października 2026 chciał wiedzieć, ile serwerów nadal pokazuje starą wersję PHP, nie musiał długo szukać. Wiele serwerów WWW podaje wersję PHP w każdej pojedynczej odpowiedzi, na przykład jako `X-Powered-By: PHP/8.2.20`. Ogólnoświatowe usługi wyszukiwania odczytują te informacje, a Unit 42 z Palo Alto Networks naliczył dla PHP2Shell ponad 22,6 mln wystawionych, potencjalnie podatnych instancji.

Dla atakujących taka informacja to skrót. Mogą wstępnie sortować cele, zamiast próbować na ślepo. Dla operatorów jest natomiast bezużyteczna, bo nie dowodzi nawet własnego stanu poprawek: dystrybucje często dostarczają poprawki jako backport bez nowego numeru wersji.

Ten artykuł pokazuje, gdzie PHP i serwer WWW ujawniają informacje o wersji i jak je wyłączyć. Mówi też otwarcie, co to daje, a czego nie.

## Gdzie wszędzie pojawiają się informacje o wersji

Wersja PHP to tylko jedno z kilku miejsc. Warto spojrzeć na całość, bo jedno zapomniane miejsce niweczy pozostałe środki.

| Miejsce | Przykład | Wyłączanie przez |
|---|---|---|
| Nagłówek HTTP z PHP | `X-Powered-By: PHP/8.3.x` | `expose_php = Off` w php.ini |
| Nagłówek HTTP serwera WWW | `Server: nginx/1.x` lub `Server: Apache/2.4.x (Debian)` | `server_tokens off;` lub `ServerTokens Prod` |
| Strony błędów serwera WWW | wiersz z wersją pod stronami 404 lub 500 | te same ustawienia, w Apache dodatkowo `ServerSignature Off` |
| Nagłówki aplikacji | własne informacje `X-Powered-By` frameworków | `fastcgi_hide_header` lub `Header unset` |
| Pliki w katalogu głównym | pliki testowe `phpinfo()`, pliki Readme i Changelog | usunąć lub zablokować |
| Komunikaty błędów PHP | ścieżki i szczegóły wersji w przeglądarce | `display_errors = Off` |

Pliki testowe z `phpinfo()` są dla atakujących najbogatszym źródłem. Zdradzają nie tylko wersję, ale całą konfigurację; więcej w artykule [Pliki phpinfo(): dlaczego muszą zniknąć](https://phpsos.de/pl/blog/phpinfo-dateien-entfernen/).

## Wyłączanie expose_php w php.ini

Według podręcznika PHP `expose_php` jest domyślnie włączone i można je zmieniać tylko w php.ini, nie w puli, nie przez `.htaccess` i nie w czasie działania. Proszę więc ustawić wartość w php.ini każdego trybu pracy, który obsługuje strony, czyli w Debianie i Ubuntu na przykład w `/etc/php/<version>/fpm/` oraz ewentualnie w `/etc/php/<version>/apache2/`.

```ini
; php.ini SAPI WWW, potem zrestartować PHP-FPM lub Apache
expose_php = Off
```

Jeśli równolegle działa kilka wersji PHP, każda wymaga własnego wpisu. Restart danej usługi jest obowiązkowy, ponieważ PHP odczytuje php.ini tylko przy starcie.

## Skracanie nagłówków Server w Nginx i Apache

Nginx domyślnie podaje swoją wersję w nagłówku `Server` i na stronach błędów. Z `server_tokens off;` pozostaje tylko nazwa produktu. Dodatkowo nagłówek `X-Powered-By`, który ustawia sama aplikacja, można odfiltrować za pomocą `fastcgi_hide_header`. Według dokumentacji Nginx sam z siebie ukrywa tylko `Status` i `X-Accel-…`, a nie `X-Powered-By`.

```nginx
# w bloku http, obowiązuje dla wszystkich stron
server_tokens off;
fastcgi_hide_header X-Powered-By;
```

W Apache `ServerTokens` steruje nagłówkiem `Server` i jednocześnie wierszem wersji pod stronami błędów. Według dokumentacji Apache ustawienie obowiązuje tylko dla całego serwera, a nie dla pojedynczego VirtualHost. Ponieważ odpowiedzi PHP-FPM przez `mod_proxy_fcgi` trafiają do innej tabeli nagłówków niż odpowiedzi samego serwera, proszę zastosować usuwanie w obu wariantach.

```apache
# konfiguracja dla całego serwera, np. /etc/apache2/conf-available/security.conf
ServerTokens Prod
ServerSignature Off

# wymaga mod_headers
<IfModule mod_headers.c>
    Header unset X-Powered-By
    Header always unset X-Powered-By
</IfModule>
```

Przed przeładowaniem proszę sprawdzić konfigurację za pomocą `nginx -t` lub `apachectl configtest`. Jak za pomocą nagłówków aktywnie włączyć ochronę odwiedzających, na przykład HSTS lub Content-Security-Policy, opisuje poradnik [Nagłówki bezpieczeństwa dla stron WWW](https://phpsos.de/pl/ratgeber/sicherheits-header/).

## Jak sprawdzić wynik z zewnątrz

Po przestawieniu proszę sprawdzić każdą domenę osobno, najlepiej także stronę błędu. Poniższe polecenia wysyłają tylko zwykłe żądania do Państwa własnych stron:

```bash
# Nagłówki strony głównej
curl -sI https://www.example.de/ | grep -iE '^(server|x-powered-by):'
# Nagłówki nieistniejącej strony
curl -sI https://www.example.de/gibt-es-nicht-4711 | grep -iE '^(server|x-powered-by):'
```

Oczekiwany jest nagłówek `Server` bez numeru wersji i brak `X-Powered-By`. Jeśli nadal widnieje tam wersja PHP, zwykle aktywny jest inny php.ini albo jakaś usługa nie została jeszcze zrestartowana. Jeśli przed serwerem stoi CDN, proszę dodatkowo sprawdzić bezpośrednio serwer źródłowy, o ile jest osiągalny.

> **Wskazówka:**
> Proszę mimo to zachować wersję PHP wewnętrznie: w inwentarzu serwerów, ze stanem pakietów i datą ostatniej kontroli. Stan poprawek dowodzi się na serwerze, jak opisano w artykule [Prawidłowe sprawdzanie wersji PHP i stanu poprawek](https://phpsos.de/pl/php2shell/php-version-pruefen/).

## Co daje ukrywanie, a czego nie

Uczciwie oceniając, wyłączenie informacji o wersji to mały środek o niewielkim nakładzie pracy. Zmniejsza prawdopodobieństwo pojawienia się w celowych wyszukiwaniach określonych wersji i ogranicza informacje, które atakujący otrzymuje bez wysiłku.

Nie chroni jednak przed zautomatyzowanymi atakami, które po prostu wysyłają żądania do każdego osiągalnego serwera. Jak przebiegają takie masowe skany, opisuje artykuł [Masowe skany w poszukiwaniu niezałatanego PHP](https://phpsos.de/pl/blog/automatisierte-massenscans/). Wobec PHP2Shell pomaga tylko aktualizacja do PHP 8.5.12, 8.4.27, 8.3.36 lub 8.2.35 albo potwierdzonego backportu, a następnie restart wszystkich procesów PHP.

Efekt uboczny jest natomiast wyjątkowo użyteczny: kto wyłącza informacje o wersji na zewnątrz, musi rzetelnie ewidencjonować wersje wewnętrznie. W sytuacji takiej jak PHP2Shell właśnie ten przegląd decyduje o tym, jak szybko wiedzą Państwo, które serwery są dotknięte.

Ukrywanie ma więc sens jako element podstawowego utwardzania, a nie jako pojedynczy środek. Należy do tej samej listy kontrolnej co wyłączone wyświetlanie błędów, usunięte pliki testowe i zablokowane wartości konfiguracji.

## Jak konkretnie pomaga PHP SOS?

- **Inwentaryzacja miejsc:** sprawdzamy nagłówki, strony błędów i katalog główny wszystkich domen pod kątem informacji o wersji i zapomnianych plików testowych.
- **Dostosowanie konfiguracji:** ustawiamy `expose_php`, nagłówki Server i filtry nagłówków w każdej wersji PHP i każdym serwerze WWW oraz kontrolowanie restartujemy usługi.
- **Wewnętrzne udokumentowanie stanu poprawek:** dokumentujemy wersje i stany pakietów tam, gdzie ich miejsce, w inwentarzu, a nie w nagłówku HTTP.
- **Włączenie w utwardzanie:** środek jest częścią naszego [utwardzania serwerów dla serwerów WWW z PHP](https://phpsos.de/pl/leistungen/server-haertung/).


## Częste pytania

**Czy expose_php = Off sprawia, że mój serwer jest bezpieczny?**  
Nie. To ustawienie usuwa tylko informację o wersji z nagłówka HTTP. Podatna wersja PHP pozostaje podatna, a zautomatyzowane ataki i tak często wysyłają swoje żądania do każdego osiągalnego serwera. Odbiera jednak atakującym łatwą wstępną selekcję i zmniejsza widoczność w wyszukiwarkach serwerów.

**Czy mogę ustawić expose_php w puli FPM lub przez .htaccess?**  
Według podręcznika PHP expose_php można zmieniać tylko w php.ini. Proszę więc ustawić wartość w php.ini każdego SAPI WWW, a następnie zrestartować PHP-FPM lub Apache.

**Dlaczego widzę X-Powered-By mimo expose_php = Off?**  
Wtedy nagłówek ustawia zwykle sama aplikacja lub framework albo aktywny jest inny plik php.ini. Nagłówek należy dodatkowo usunąć w serwerze WWW: za pomocą fastcgi_hide_header w Nginx lub Header unset w Apache.

**Jak sprawdzić stan poprawek, jeśli wersja nie jest już widoczna?**  
Na samym serwerze: menedżer pakietów, changelog pakietu z numerami CVE i czas uruchomienia procesów PHP. Informacja w nagłówku HTTP i tak nie była dowodem, ponieważ dystrybucje często wgrywają backporty bez nowego numeru wersji.

## Źródła

- [Podręcznik PHP: ustawienia Core (expose_php)](https://www.php.net/manual/en/ini.core.php)
- [Nginx: server_tokens (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html)
- [Apache: ServerTokens i ServerSignature](https://httpd.apache.org/docs/2.4/mod/core.html)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
