Actuele situatie: PHP2Shell. Twee kritieke PHP-kwetsbaarheden (CVSS 9.2) maken schadelijke code zonder inloggen mogelijk. Patches sinds 21-10-2026.Wat u nu moet doen →

expose_php en Server-header: versiegegevens verbergen

PHP, Nginx en Apache noemen standaard hun versienummer in elk antwoord. Dat beschermt niet tegen aanvallen, maar geeft scanners een handige lijst met doelwitten. Zo schakelt u het uit en houdt u toch het overzicht.

Stand 5 min. leestijdHardening en configuratie

Kort gezegd: Met expose_php = Off in de php.ini verdwijnt de header X-Powered-By: PHP/…. Daarbij horen server_tokens off; in Nginx en ServerTokens Prod en ServerSignature Off in Apache. Dat maakt geen server veiliger, maar ontneemt geautomatiseerde scans een kant-en-klare versielijst. Uw eigen patchstatus controleert u daarna via pakketbeheer en processen, niet via headers.

Het visitekaartje in elk antwoord

Wie na 21 oktober 2026 wilde weten hoeveel servers nog een oude PHP-versie tonen, hoefde niet lang te zoeken. Veel webservers noemen hun PHP-versie in elk afzonderlijk antwoord, bijvoorbeeld als X-Powered-By: PHP/8.2.20. Internetbrede zoekdiensten lezen deze gegevens mee, en Unit 42 van Palo Alto Networks telde voor PHP2Shell meer dan 22,6 miljoen blootgestelde, potentieel kwetsbare instanties.

Voor aanvallers is zo'n vermelding een sluiproute. Ze kunnen doelwitten vooraf sorteren in plaats van blind te proberen. Voor beheerders is ze daarentegen nutteloos, want ze bewijst niet eens de eigen patchstatus: distributies leveren correcties vaak als backport uit zonder nieuw versienummer.

Dit artikel laat zien waar PHP en webserver versie-informatie prijsgeven en hoe u de vermeldingen uitschakelt. Het zegt ook openlijk wat dat oplevert en wat niet.

Waar versiegegevens overal opduiken

De PHP-versie is slechts één van meerdere plaatsen. Een volledige blik loont, omdat één enkele vergeten plek de andere maatregelen waardeloos maakt.

Vindplaats Voorbeeld Uitschakelen via
HTTP-header van PHP X-Powered-By: PHP/8.3.x expose_php = Off in de php.ini
HTTP-header van de webserver Server: nginx/1.x of Server: Apache/2.4.x (Debian) server_tokens off; resp. ServerTokens Prod
Foutpagina's van de webserver Versieregel onder 404- of 500-pagina's dezelfde instellingen, in Apache aanvullend ServerSignature Off
Header van de applicatie eigen X-Powered-By-vermeldingen van frameworks fastcgi_hide_header resp. Header unset
Bestanden in de webroot phpinfo()-testbestanden, readme- en changelogbestanden verwijderen of afsluiten
PHP-foutmeldingen Paden en versiedetails in de browser display_errors = Off

Testbestanden met phpinfo() zijn daarbij de rijkste bron voor aanvallers. Ze verraden niet alleen de versie, maar de hele configuratie; meer daarover in het artikel phpinfo()-bestanden: waarom ze moeten verdwijnen.

expose_php uitschakelen in de php.ini

Volgens de PHP-handleiding is expose_php standaard ingeschakeld en alleen in de php.ini te wijzigen, niet in de pool, niet via .htaccess en niet tijdens de uitvoering. Stel de waarde daarom in de php.ini in van elke uitvoeringsmodus die websites uitlevert, dus bij Debian en Ubuntu bijvoorbeeld onder /etc/php/<version>/fpm/ en eventueel /etc/php/<version>/apache2/.

; php.ini van de web-SAPI, herstart daarna PHP-FPM resp. Apache
expose_php = Off

Draaien er meerdere PHP-versies parallel, dan heeft elke versie een eigen vermelding nodig. Een herstart van de betreffende service is verplicht, want PHP leest de php.ini alleen bij het opstarten.

Server-headers in Nginx en Apache inkorten

Nginx noemt zijn versie standaard in de Server-header en op foutpagina's. Met server_tokens off; blijft alleen de productnaam over. Daarnaast kan een X-Powered-By-header die de applicatie zelf instelt, met fastcgi_hide_header worden weggefilterd. Volgens de Nginx-documentatie verbergt Nginx uit zichzelf alleen Status en X-Accel-…, niet X-Powered-By.

# in het http-blok, geldt voor alle websites
server_tokens off;
fastcgi_hide_header X-Powered-By;

In Apache bepaalt ServerTokens de Server-header en tegelijk de versieregel onder foutpagina's. De instelling geldt volgens de Apache-documentatie alleen server-breed, niet per VirtualHost. Omdat PHP-FPM-antwoorden via mod_proxy_fcgi in een andere headertabel terechtkomen dan antwoorden van de server zelf, stelt u het verwijderen in beide varianten in.

# server-brede configuratie, bijv. /etc/apache2/conf-available/security.conf
ServerTokens Prod
ServerSignature Off

# vereist mod_headers
<IfModule mod_headers.c>
    Header unset X-Powered-By
    Header always unset X-Powered-By
</IfModule>

Controleer de configuratie vóór het opnieuw laden met nginx -t respectievelijk apachectl configtest. Hoe u via headers actief bescherming voor bezoekers inschakelt, bijvoorbeeld met HSTS of een Content-Security-Policy, beschrijft de gids Beveiligingsheaders voor websites.

Zo controleert u het resultaat van buitenaf

Controleer na de omschakeling elk domein afzonderlijk, bij voorkeur ook een foutpagina. De volgende opdrachten sturen alleen normale verzoeken naar uw eigen websites:

# Headers van de startpagina
curl -sI https://www.example.de/ | grep -iE '^(server|x-powered-by):'
# Headers van een niet-bestaande pagina
curl -sI https://www.example.de/gibt-es-nicht-4711 | grep -iE '^(server|x-powered-by):'

Verwacht wordt een Server-header zonder versienummer en geen X-Powered-By. Staat er nog steeds een PHP-versie, dan is meestal een andere php.ini actief of is een service nog niet herstart. Staat er een CDN voor de server, controleer dan aanvullend de oorspronkelijke server rechtstreeks, voor zover die bereikbaar is.

Tip

Leg de PHP-versie intern toch vast: in uw serverinventaris, met pakketstatus en datum van de laatste controle. De patchstatus bewijst u via de server, zoals beschreven onder PHP-versie en patchstatus juist controleren.

Wat het verbergen oplevert en wat niet

Eerlijk beschouwd is het uitschakelen van versiegegevens een kleine maatregel met weinig inspanning. Ze verlaagt de kans om op te duiken in gerichte zoekacties naar bepaalde versies en vermindert de informatie die een aanvaller zonder moeite krijgt.

Ze beschermt echter niet tegen geautomatiseerde aanvallen die hun verzoeken gewoon naar elke bereikbare server sturen. Hoe zulke massascans verlopen, beschrijft het artikel Massascans naar ongepatcht PHP. Tegen PHP2Shell helpt alleen de update naar PHP 8.5.12, 8.4.27, 8.3.36 of 8.2.35 respectievelijk een bevestigde backport, gevolgd door de herstart van alle PHP-processen.

Een neveneffect is daarentegen bijzonder nuttig: wie versiegegevens naar buiten uitschakelt, moet zijn versies intern netjes vastleggen. In een situatie als PHP2Shell bepaalt juist dat overzicht hoe snel u weet welke servers zijn getroffen.

Zinvol is het verbergen daarom als onderdeel van een basishardening, niet als afzonderlijke maatregel. Het hoort op dezelfde checklist als uitgeschakelde foutuitvoer, verwijderde testbestanden en vergrendelde configuratiewaarden.

Hoe helpt PHP SOS concreet?

  • Vindplaatsen inventariseren: wij controleren headers, foutpagina's en webroot van alle domeinen op versiegegevens en vergeten testbestanden.
  • Configuratie aanpassen: wij stellen expose_php, Server-headers en headerfilters in voor elke PHP-versie en elke webserver en herstarten de services gecontroleerd.
  • Patchstatus intern aantonen: wij documenteren versies en pakketstanden waar ze thuishoren, in de inventaris in plaats van in de HTTP-header.
  • In de hardening inpassen: de maatregel maakt deel uit van onze serverhardening voor PHP-webservers.

Veelgestelde vragen

Maakt expose_php = Off mijn server veilig?

Nee. De instelling verwijdert alleen de versievermelding uit de HTTP-header. Een kwetsbare PHP-versie blijft kwetsbaar en geautomatiseerde aanvallen proberen hun verzoeken vaak toch bij elke bereikbare server. U ontneemt aanvallers wel een eenvoudige voorselectie en verlaagt de zichtbaarheid in zoekmachines voor servers.

Kan ik expose_php in de FPM-pool of via .htaccess instellen?

Volgens de PHP-handleiding is expose_php alleen in de php.ini te wijzigen. Stel de waarde daarom in de php.ini van elke web-SAPI in en herstart daarna PHP-FPM of Apache.

Waarom zie ik X-Powered-By ondanks expose_php = Off?

Dan stelt meestal de applicatie of een framework de header zelf in, of is er een andere php.ini actief. Verwijder de header aanvullend in de webserver: met fastcgi_hide_header in Nginx of Header unset in Apache.

Hoe controleer ik mijn patchstatus als de versie niet meer zichtbaar is?

Via de server zelf: pakketbeheer, pakketchangelog met de CVE-nummers en de starttijd van de PHP-processen. De vermelding in de HTTP-header was nooit een bewijs, want distributies voeren backports vaak door zonder nieuw versienummer.

Bronnen

Direct contact

Elk uur telt. Schrijf ons nu.

Beschrijf kort het systeem, de PHP-versie en wat u opmerkt. Wij nemen contact op, brengen de situatie in kaart en werken op afstand tot het incident is afgerond en gedocumenteerd.

Directe hulp