# expose_php и Server заглавия: скриване на данните за версиите

> expose_php, X-Powered-By и Server заглавие: къде PHP и уеб сървърът издават версията си, как да го спрете в php.ini, Nginx и Apache и как да го проверите.

Източник: https://phpsos.de/bg/blog/expose-php-versionsangaben/  
Актуалност: 25.10.2026  
Доставчик: PHP SOS, Спешна помощ за PHP и сигурност на сървъри. Незабавна помощ по WhatsApp: https://wa.me/491736494914?text=%D0%97%D0%B4%D1%80%D0%B0%D0%B2%D0%B5%D0%B9%D1%82%D0%B5%2C%20PHP%20SOS%2C%20%D0%B8%D0%BC%D0%B0%D0%BC%D0%B5%20%D0%BD%D1%83%D0%B6%D0%B4%D0%B0%20%D0%BE%D1%82%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%20%D1%81%20%D0%BD%D0%B0%D1%88%D0%B8%D1%8F%20PHP%20%D1%81%D1%8A%D1%80%D0%B2%D1%8A%D1%80.%20%D0%A4%D0%B8%D1%80%D0%BC%D0%B0%3A%20%E2%80%A6%20%D0%A3%D0%B5%D0%B1%D1%81%D0%B0%D0%B9%D1%82%3A%20%E2%80%A6

**Накратко:** С `expose_php = Off` в php.ini заглавието `X-Powered-By: PHP/…` изчезва. Към това се добавят `server_tokens off;` в Nginx, както и `ServerTokens Prod` и `ServerSignature Off` в Apache. Това не прави сървъра по-сигурен, но отнема на автоматизираните сканирания готов списък с версии. Собственото състояние на пачовете проверявате след това чрез управлението на пакети и процесите, не чрез заглавия.

## Визитката във всеки отговор

Който след 21 октомври 2026 г. е искал да знае колко сървъра още показват стара версия на PHP, не е трябвало да търси дълго. Много уеб сървъри посочват версията на PHP във всеки отделен отговор, например като `X-Powered-By: PHP/8.2.20`. Услуги за търсене в целия интернет четат тези данни, а Unit 42 на Palo Alto Networks преброи за PHP2Shell повече от 22,6 милиона изложени, потенциално уязвими инстанции.

За атакуващите такава информация е пряк път. Те могат да подреждат целите предварително, вместо да пробват на сляпо. За операторите тя е безполезна, защото не доказва дори собственото състояние на пачовете: дистрибуциите често доставят корекциите като backport без нов номер на версията.

Тази статия показва къде PHP и уеб сървърите издават информация за версията и как да спрете данните. Тя казва и открито какво носи това и какво не.

## Къде навсякъде се появяват данни за версията

Версията на PHP е само едно от няколко места. Пълният поглед си струва, защото едно-единствено забравено място обезценява другите мерки.

| Място на находката | Пример | Спиране чрез |
|---|---|---|
| HTTP заглавие от PHP | `X-Powered-By: PHP/8.3.x` | `expose_php = Off` в php.ini |
| HTTP заглавие на уеб сървъра | `Server: nginx/1.x` или `Server: Apache/2.4.x (Debian)` | `server_tokens off;` респ. `ServerTokens Prod` |
| Страници с грешки на уеб сървъра | ред с версия под страниците 404 или 500 | същите настройки, в Apache допълнително `ServerSignature Off` |
| Заглавия на приложението | собствени `X-Powered-By` на рамки | `fastcgi_hide_header` респ. `Header unset` |
| Файлове в уеб корена | тестови файлове с `phpinfo()`, файлове readme и changelog | изтриване или блокиране |
| Съобщения за грешки на PHP | пътища и подробности за версията в браузъра | `display_errors = Off` |

Тестовите файлове с `phpinfo()` са най-богатият източник за атакуващите. Те издават не само версията, а цялата конфигурация; повече по темата в статията [Файлове с phpinfo(): защо трябва да изчезнат](https://phpsos.de/bg/blog/phpinfo-dateien-entfernen/).

## Изключване на expose_php в php.ini

Според ръководството на PHP `expose_php` е включен по подразбиране и може да се променя само в php.ini, не в пула, не чрез `.htaccess` и не по време на изпълнение. Затова задайте стойността в php.ini на всеки режим на работа, който връща сайтове, тоест при Debian и Ubuntu например в `/etc/php/<version>/fpm/` и при нужда в `/etc/php/<version>/apache2/`.

```ini
; php.ini на уеб SAPI, след това рестартирайте PHP-FPM респ. Apache
expose_php = Off
```

Ако успоредно работят няколко версии на PHP, всяка се нуждае от своя запис. Рестартирането на съответната услуга е задължително, защото PHP чете php.ini само при стартиране.

## Съкращаване на Server заглавията в Nginx и Apache

Nginx по подразбиране посочва версията си в заглавието `Server` и на страниците с грешки. С `server_tokens off;` остава само името на продукта. Допълнително заглавие `X-Powered-By`, което приложението задава само, може да се филтрира с `fastcgi_hide_header`. Според документацията на Nginx той скрива от само себе си само `Status` и `X-Accel-…`, не и `X-Powered-By`.

```nginx
# в блока http, важи за всички сайтове
server_tokens off;
fastcgi_hide_header X-Powered-By;
```

В Apache `ServerTokens` управлява заглавието `Server` и едновременно реда с версията под страниците с грешки. Според документацията на Apache настройката важи само за целия сървър, не за всеки VirtualHost. Тъй като отговорите на PHP-FPM през `mod_proxy_fcgi` попадат в друга таблица със заглавия, различна от тази на отговорите на самия сървър, задайте премахването и в двата варианта.

```apache
# конфигурация за целия сървър, напр. /etc/apache2/conf-available/security.conf
ServerTokens Prod
ServerSignature Off

# изисква mod_headers
<IfModule mod_headers.c>
    Header unset X-Powered-By
    Header always unset X-Powered-By
</IfModule>
```

Преди презареждане проверете конфигурацията с `nginx -t` респективно `apachectl configtest`. Как да включите активна защита на посетителите чрез заглавия, например с HSTS или Content-Security-Policy, описва ръководството [Хедъри за сигурност на уебсайтове](https://phpsos.de/bg/ratgeber/sicherheits-header/).

## Така проверявате резултата отвън

След прехода проверете всеки домейн поотделно, по възможност и страница с грешка. Следните команди изпращат само нормални заявки към Вашите собствени сайтове:

```bash
# Заглавия на началната страница
curl -sI https://www.example.de/ | grep -iE '^(server|x-powered-by):'
# Заглавия на несъществуваща страница
curl -sI https://www.example.de/gibt-es-nicht-4711 | grep -iE '^(server|x-powered-by):'
```

Очаква се заглавие `Server` без номер на версия и без `X-Powered-By`. Ако там все още стои версия на PHP, най-често е активен друг php.ini или някоя услуга още не е рестартирана. Ако пред сървъра има CDN, проверете допълнително директно сървъра на произход, доколкото е достъпен.

> **Съвет:**
> Все пак водете версията на PHP вътрешно: във Вашия инвентар на сървърите, със състоянието на пакетите и датата на последната проверка. Състоянието на пачовете доказвате през сървъра, както е описано в [Правилна проверка на версията на PHP и на състоянието на пачовете](https://phpsos.de/bg/php2shell/php-version-pruefen/).

## Какво носи скриването и какво не

Честно погледнато, изключването на данните за версията е малка мярка с малко усилия. Тя намалява вероятността да се появите в целенасочени търсения на определени версии и намалява информацията, която атакуващият получава без труд.

Тя обаче не защитава от автоматизирани атаки, които просто изпращат заявките си до всеки достъпен сървър. Как протичат такива масови сканирания, описва статията [Масови сканирания за непачнат PHP](https://phpsos.de/bg/blog/automatisierte-massenscans/). Срещу PHP2Shell помага само актуализацията до PHP 8.5.12, 8.4.27, 8.3.36 или 8.2.35 респективно потвърден backport, последвана от рестартиране на всички PHP процеси.

Един страничен ефект обаче е изключително полезен: който изключва данните за версията навън, трябва да отчита чисто версиите си вътрешно. В положение като PHP2Shell точно този преглед решава колко бързо ще разберете кои сървъри са засегнати.

Затова скриването има смисъл като част от основното заздравяване, не като единична мярка. То принадлежи в същия контролен списък като изключени изходи на грешки, изтрити тестови файлове и заключени конфигурационни стойности.

## Как помага PHP SOS конкретно?

- **Отчитане на местата:** проверяваме заглавията, страниците с грешки и уеб корена на всички домейни за данни за версии и забравени тестови файлове.
- **Адаптиране на конфигурацията:** задаваме `expose_php`, Server заглавията и филтрите за заглавия във всяка версия на PHP и всеки уеб сървър и рестартираме услугите контролирано.
- **Вътрешно доказване на състоянието на пачовете:** документираме версиите и състоянието на пакетите там, където им е мястото, в инвентара, а не в HTTP заглавието.
- **Вграждане в заздравяването:** мярката е част от нашето [заздравяване на сървъри за PHP уеб сървъри](https://phpsos.de/bg/leistungen/server-haertung/).


## Често задавани въпроси

**Прави ли expose_php = Off моя сървър сигурен?**  
Не. Настройката премахва само данните за версията от HTTP заглавието. Уязвима версия на PHP остава уязвима, а автоматизираните атаки често така или иначе изпробват заявките си на всеки достъпен сървър. Скриването обаче отнема на атакуващите лесен предварителен подбор и намалява видимостта на сървъра в търсачките за сървъри.

**Мога ли да задам expose_php в пула на FPM или чрез .htaccess?**  
Според ръководството на PHP expose_php може да се променя само в php.ini. Затова задайте стойността в php.ini на всеки уеб SAPI и след това рестартирайте PHP-FPM или Apache.

**Защо виждам X-Powered-By въпреки expose_php = Off?**  
Тогава най-често самото приложение или рамка задава заглавието, или е активен друг php.ini. Премахнете заглавието допълнително в уеб сървъра: с fastcgi_hide_header в Nginx или Header unset в Apache.

**Как да проверя състоянието на пачовете, ако версията вече не се вижда?**  
Чрез самия сървър: управлението на пакети, changelog на пакета с номерата на CVE и началното време на PHP процесите. Данните в HTTP заглавието така или иначе не бяха доказателство, защото дистрибуциите често внасят backport корекции без нов номер на версията.

## Източници

- [Ръководство на PHP: основни настройки (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 и ServerSignature](https://httpd.apache.org/docs/2.4/mod/core.html)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
