Direct naar inhoud

Versie-informatie in HTTP-headers

CWE-200OWASP A05:2021Bijgewerkt 3 september 20264 min leestijd

Headers als Server, X-Powered-By en X-AspNet-Version vermelden welke software en welke versie u draait. Daarmee kan een aanvaller in één opzoekactie vaststellen welke bekende kwetsbaarheden op u van toepassing zijn. Het weghalen verhelpt niets, maar het maakt geautomatiseerd zoeken naar kwetsbare doelen wel aanzienlijk minder effectief.

Aanvallers zoeken zelden eerst een doelwit en dan een kwetsbaarheid. Vaker gaat het andersom: er is een bekend probleem in een specifieke versie, en er wordt geautomatiseerd gezocht naar systemen die die versie draaien. Wie zijn versienummer in de headers zet, meldt zich vrijwillig aan voor die zoekopdracht. Wat er lekt is specifiek, en het weghalen is eenvoudig.

Wat lekt er in de headers?

Bij elk HTTP-antwoord stuurt een server een aantal headers mee die niets met uw applicatie te maken hebben maar met de software eronder. De bekendste is Server, die de webserver en vaak de exacte versie vermeldt. Daarnaast zijn er X-Powered-By voor de gebruikte programmeertaal, en framework-specifieke varianten die het contentmanagementsysteem of de applicatieomgeving benoemen.

Van versie-informatie in HTTP-headers spreken we wanneer die waarden zo gedetailleerd zijn dat een aanvaller er direct bekende kwetsbaarheden bij kan zoeken. Het verschil tussen Server: nginx en Server: nginx/1.18.0 (Ubuntu) is precies dat: de eerste zegt welk product, de tweede zegt welk product, welke versie en welk besturingssysteem.

De vergelijking met een naambordje gaat maar half op, want een naambordje is nuttig. Dit is eerder een bordje waarop staat welk slot er in de deur zit en uit welk productiejaar het komt. Voor de bewoner voegt het niets toe; voor wie de terugroepacties van dat merk heeft gelezen wel.

Welke headers verraden uw versies?

Kwetsbaar:

HTTP/1.1 200 OK
Server: Apache/2.4.29 (Ubuntu)
X-Powered-By: PHP/7.2.24
X-AspNet-Version: 4.0.30319
X-Generator: Drupal 9.3.6 (https://www.drupal.org)

Vier headers, vier stukken informatie waar een aanvaller niets voor hoefde te doen. Hij weet nu welke webserver, welke taalversie, welk applicatieplatform en welk contentmanagementsysteem er draaien. De vervolgstap is een opzoekactie in een publieke kwetsbaarhedendatabase, en die levert per versie een lijst met bekende problemen en soms kant-en-klare aanvalscode.

Wat dit vooral doet, is u zichtbaar maken voor grootschalig geautomatiseerd zoeken. Er wordt continu op internet gescand naar systemen die een specifieke kwetsbare versie draaien. Uw organisatie hoeft daarvoor niet interessant te zijn; het volstaat dat u antwoordt.

Veilig:

# nginx: alleen de productnaam, geen versie
server_tokens off;

# En wat de applicatie erachter toevoegt, weghalen bij het doorgeven
proxy_hide_header X-Powered-By;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-Generator;
# Apache
ServerTokens Prod
ServerSignature Off
// En in de applicatie zelf
app.disable('x-powered-by');

Het antwoord is nu aanzienlijk stiller:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
X-Content-Type-Options: nosniff

Een reverse proxy is daarbij de meest betrouwbare plek om dit af te dwingen, omdat u daar de headers van elke achterliggende dienst in één keer kunt opschonen, ook die van componenten waarvan u de configuratie niet in de hand hebt.

Beschouw dit als opruimen, niet als beveiligen. Een verwijderde header maakt een verouderde component niet minder verouderd. De maatregel is goedkoop en zinvol, maar hij staat of valt met het feit dat u de onderliggende software daadwerkelijk bijhoudt.

Wat is de impact van versie-informatie in headers?

De ernst is laag, en dat is een eerlijke inschatting: er is geen aanval die door deze headers mogelijk wordt gemaakt. Wat ze doen is de verkenningsfase van een aanvaller inkorten van enig uitzoekwerk naar één blik.

De praktische betekenis zit in de schaal waarop tegenwoordig wordt gescand. Wanneer er een ernstige kwetsbaarheid in een veelgebruikt product bekend wordt, begint binnen uren het geautomatiseerd zoeken naar systemen die de kwetsbare versie draaien. Systemen die hun versie vermelden, komen in die lijst terecht. Systemen die dat niet doen, moeten met meer moeite worden onderzocht, en bij grootschalig scannen wordt die moeite meestal niet genomen.

Er is nog een tweede effect dat verder gaat dan deze headers zelf. Een antwoord dat volledig op standaardinstellingen draait, is voor een ervaren tester een signaal: als deze eenvoudige aanpassing niet is gedaan, is de kans groot dat er meer standaardinstellingen zijn blijven staan. De headers zijn dan minder een kwetsbaarheid dan een indicator.

Hoe spoor je versie-informatie in headers op?

Een tester bekijkt de headers van een aantal verschillende antwoorden: de startpagina, een statisch bestand, een API-endpoint en een foutpagina. Die geven vaak verschillende informatie prijs, omdat ze door verschillende componenten worden afgehandeld: een statisch bestand komt van de webserver, een API-antwoord van de applicatie erachter.

Daarnaast wordt gekeken naar minder opvallende bronnen: HTML-commentaar met een generatoraanduiding, meta-tags, de bestandsnamen van standaard meegeleverde stylesheets, en cookienamen die het platform verraden. Ook worden foutpagina’s opgevraagd, omdat die vaak een standaardpagina van de server zijn met versie-informatie in de voettekst. Verder wordt getest of de headers ook worden opgeschoond op routes die buiten de reverse proxy om worden bediend. AssistSec gebruikt de gevonden versies vervolgens om te toetsen of er bekende kwetsbaarheden op van toepassing zijn, want dat is uiteindelijk waar het om gaat, niet om de header zelf.

Hoe voorkom je versie-informatie in headers?

  • Schakel het meesturen van versie-informatie uit in uw webserver.
  • Verwijder X-Powered-By en framework-specifieke headers in de applicatie of bij de reverse proxy.
  • Schoon de headers centraal op bij de proxy, zodat ook componenten die u niet beheert worden meegenomen.
  • Controleer de headers op verschillende soorten antwoorden: pagina’s, statische bestanden, API’s en foutpagina’s.
  • Vervang standaard foutpagina’s door eigen pagina’s zonder versie-informatie of servernaam.
  • Verwijder generator-meta-tags en verraderlijk HTML-commentaar uit uw sjablonen.
  • Beschouw dit als aanvulling op het bijhouden van uw componenten, nooit als vervanging daarvan.
  • Controleer de instelling opnieuw na een migratie of upgrade, want standaardwaarden keren dan terug.

Bronnen

Veelgestelde vragen

Is dit niet gewoon security through obscurity?

Gedeeltelijk, en het wordt dan ook nooit als vervanging van patchen gepresenteerd. Het verschil zit in schaal: aanvallers scannen het internet geautomatiseerd op specifieke versies. Wie die versie niet vermeldt, valt buiten die selectie en wordt hooguit gericht onderzocht, dat is een reëel verschil in blootstelling.

Kan een aanvaller de versie niet toch achterhalen?

Vaak wel, met meer moeite. Gedrag bij ongebruikelijke verzoeken, de volgorde van headers, de exacte formulering van foutpagina's en de aanwezigheid van standaardbestanden verraden veel. Het weghalen van de header verhoogt de drempel; het maakt vaststelling niet onmogelijk.

Welke headers moet ik weghalen?

Server of X-Powered-By met een versienummer, en de framework-specifieke varianten zoals X-AspNet-Version, X-AspNetMvc-Version, X-Generator en X-Drupal-Cache. Kijk daarnaast naar wat uw eigen applicatie toevoegt; ook interne bouwnummers horen er niet in.

Mag ik de Server-header helemaal weglaten?

Ja, hij is niet verplicht. Sommige servers laten hem niet volledig verwijderen maar wel inkorten tot de productnaam zonder versie. Een reverse proxy kan de header desnoods herschrijven of verwijderen voordat het antwoord naar buiten gaat.

Verwante artikelen

Druk op / om te zoeken · Esc