Openbare-sleutel-pinning met HPKP-rapportage uitrollen

Emily Stark

Het gebruik van SSL op je site is een belangrijke manier om de beveiliging en privacy van je gebruikers te waarborgen. Maar met het aanzetten van SSL ben je er nog niet: je kunt nog veel meer doen om de beveiliging van je site te verbeteren. Je kunt bijvoorbeeld het Secure-kenmerk instellen voor je cookies, HTTP Strict Transport Security aanzetten of Content Security Policy gebruiken om de rechten van je site te beperken. Het kan soms lastig zijn om deze krachtige functies te implementeren. Chrome 46 bevat een functie met de naam HPKP-rapportage waarmee je een strengere vorm van SSL kunt uitrollen.

Wat betekenen al deze acroniemen?

De beveiliging op het huidige internet is afhankelijk van SSL-certificaten: cryptografische handtekeningen die bewijzen dat een website is wie deze zegt te zijn. Als je browser een verzoek stuurt naar een URL zoals https://developers.google.com, levert de server een SSL-certificaat. Als het certificaat geldig is, staat de browser het verzoek toe en wordt de website-URL met een groen hangslot in de adresbalk getoond.

Wat is een geldig certificaat? Een certificaat is alleen geldig als het is ondertekend door een certificeringsinstantie (CA) of door een ander certificaat dat is ondertekend door een CA (een tussenliggende CA). Browsers en besturingssystemen worden geleverd met een lijst van enkele honderden CA's die worden vertrouwd om certificaten uit te geven. Het probleem is echter dat elk van deze CA's standaard certificaten kan uitgeven voor elke website. Als een van deze partijen wordt gehackt of zich misdraagt, kan dat verwoestend zijn voor het hele web.

Voer HTTP Public Key Pinning (HPKP) in. Met deze standaard kunnen websites een HTTP-header sturen die de browser opdracht geeft delen van de SSL-certificaatketen te onthouden (of vast te zetten). De browser weigert dan volgende verbindingen die niet overeenkomen met de pins die deze eerder heeft gekregen. Hier volgt een voorbeeld van een HPKP-header:

Public-Key-Pins:  
       pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=";  
       pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=";  
       max-age=259200

Deze header specificeert 2 certificaathashes als pins. De ene is een hash van een certificaat in de certificaatketen van de site en de andere is een back-uppincode of een hash van een certificaat dat de site kan gebruiken als het certificaat moet worden gerouleerd. De koptekst bevat ook een max-age-waarde. Nadat dat aantal seconden is verstreken, vergeet de browser de pincode.

Ga voor meer informatie over HPKP in het algemeen naar de specificatie of de uitstekende blogpost van Chrome-ontwikkelaar Chris Palmer.

Moet ik HPKP nu meteen aanzetten?

Dat hoeft niet per se. Als je HPKP implementeert, is het vrij makkelijk om een fout te maken en per ongeluk een DoS-aanval op je site uit te voeren. Als je je site vastzet aan een set certificaten en daarna een nieuwe set moet implementeren, hebben gebruikers die de vastgezette certificaten hebben gezien geen toegang tot je site totdat de vastgezette certificaten verlopen (op basis van de waarde max-age in de koptekst).

Omdat het lastig is om HPKP goed te gebruiken, wordt het momenteel voornamelijk gebruikt door een handvol bekende, beveiligingsgevoelige sites. Als je besluit HPKP aan te zetten, moet je beginnen met een zeer korte max-age-waarde en deze geleidelijk verhogen als je geen problemen ondervindt.

Wat is HPKP-rapportage en hoe helpt dit?

HPKP-rapportage, beschikbaar in Chrome 46, is een functie die je kunt gebruiken om onjuiste configuraties op te sporen terwijl je HPKP uitrolt.

Je kunt beginnen door de Public-Key-Pins-Report-Only-header te sturen in plaats van de Public-Key-Pins-header:

Public-Key-Pins-Report-Only: 
       max-age=2592000;  
       pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";  
       pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=";  
report-uri="https://example.net/pkp-report"

Als je site een dergelijke header stuurt, verifieert Chrome of de huidige verbinding overeenkomt met de pins. Als dit niet het geval is, wordt er een rapport naar de report-uri gestuurd. Chrome blokkeert nooit verzoeken op basis van de pins in een Report-Only-header. Dit is dus een veilige manier om HPKP uit te proberen en te zien of dit problemen veroorzaakt voor je gebruikers, zonder het risico te lopen dat je site wordt getroffen door een DoS-aanval.

Een Report-Only-header is alleen van toepassing op het verzoek waarop deze is ontvangen. De browser onthoudt alleen-rapportage-pinnen niet zoals echte pinnen. Zo kun je je configuratie testen zonder je zorgen te maken over het cachen van slechte waarden in de browsers van je gebruikers. Je kunt de configuratie incrementeel uitrollen (bijvoorbeeld op één bron) om te voorkomen dat je server wordt overspoeld met rapporten.

Als je de echte Public-Key-Pins-header uitrolt om je pins af te dwingen, kun je ook een report-uri-waarde in die header opnemen, zodat je rapporten blijft krijgen als er problemen optreden.

Wat staat er in een HPKP-schendingsrapport?

Een HPKP-schendingsrapport is een JSON-bericht dat in een HTTP POST-verzoek wordt gestuurd naar je ingestelde report-uri. De lijst met velden vind je in de specificatie, maar ik licht er hier twee uit: served-certificate-chain en validated-certificate-chain. De served-certificate-chain is het certificaat precies zoals Chrome het heeft ontvangen toen de SSL-verbinding voor het verzoek werd ingesteld. De validated-certificate-chain is daarentegen de keten die Chrome opnieuw heeft opgebouwd bij de poging om het certificaat van de server te valideren. Dit kan verrassend genoeg verschillen van de served-certificate-chain. Verschillende clients voeren certificaatvalidatie op verschillende manieren uit. Dit is een veelvoorkomende oorzaak van onjuiste HPKP-configuraties. Controleer dit veld als je onverwachte rapporten krijgt.

Nog een laatste addertje onder het gras

Als je HPKP-rapportage implementeert, onthoud dan dat Chrome pinvalidatie uitvoert voor alle verzoeken, inclusief verzoeken om rapporten te sturen. Als je HPKP hebt geïmplementeerd voor je site, wil je HPKP-rapporten waarschijnlijk naar een ander domein sturen dat je niet hebt vastgezet. Anders leidt een pin-schending op je site tot een rapport naar hetzelfde domein, dat ook de pin-schending niet doorstaat. Je krijgt het rapport dan niet.

Als je geen ander domein bij de hand hebt, kun je een service zoals report-uri.io proberen, die schendingsrapporten voor je verwerkt.