Skip to content

Rijks POC

Rijk van Zanten edited this page Jan 24, 2017 · 2 revisions

HTTP vs HTTPS

Hoofdvraag: Hoe maak je verbindingen veilig

Het probleem:

In een standaard http-request is alle data open. De inhoud van zo'n http-request ziet er doorgaands zo uit en gaat onbeveiligd over de lijn:

GET /contact HTTP/1.1
Host: cmd-amsterdam.nl
Connection: close
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8.0.3) 
    Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,text/html,text/plain,image/png,image/jpeg,image/gif
Accept-Charset: ISO-8859-1,utf-8 GET /contact HTTP/1.1

Dit ziet er vrij onschuldig uit, en dat is het bij een GET request ook wel, maar het probleem komt naar boven wanneer het om een post-request gaat, waarbij gevoelige info wordt verstuurd.

POST /results HTTP/1.1
Host: misofo.me
Content-Type: application/x-www-form-urlencoded
name=Rijk&message=Supergevoelige+patienten+gegevens+joo

Hier hebben we ineens een groot beveiligings probleem. We willen simpelweg niet dat er gevoelige data van patienten zo onbeveiligd over het internet vliegt.

Wat te doen:

De beste oplossing op dit moment is het versleutelen van je http-verkeer. Hiervoor maken we gebruik van HTTPS (de S is voor Secure, big surprise).

HTTPS versleuteld encrypt het verkeer en decrypt het pas op de server. Daarnaast vindt er een handshake plaats die checked of de server ook echt de server is die hij zegt te zijn. Hiervoor is een certificate nodig. Een certificate is een soort ID-kaart voor je server. Deze certificaten zijn IP-adres en domein gebonden, en zijn alleen te krijgen bij een speciale provider (die dus de eindverantwoordelijkheid voor de certificaten).

Laatst werd ontdekt dat er een certificate-partij te pas en te onpas certificaten uitdeelde aan malafide partijen. Browsers en zoekmachines tonen nu alsnog een waarschuwing bij sites die gebruik maken van certificaten van deze partij.

Hoe te implementeren:

De meeste certificaat verstrekkers vragen een vergoeding voor hun verantwoordelijkheid.

HTTPS implementeren kan op twee plaatsen; in een 'standaard' webserver, zoals Apache of Nginx, of in een Node app.

Om een certificate in te stellen op apache of nginx moet je een aantal configuratie files aanpassen. De makkelijkste manier om dit gedaan te krijgen is door een tutorial van DigitalOcean te volgen.

Als je een Node app hebt gebouwd die gebruik maakt van Express, dan kun je een fantastisch stukje middleware gebruiken die automagisch een certificate aanvraagd bij Letsencrypt, en al het verkeer gelijk doorstuurt naar https. Er is ook een variant beschikbaar voor apps die gebruik maken van Hapi / Koa of de node default HTTP (maar die zijn wel wat lastiger goed te implementeren).


Uitwerking

Zoals te zien is aan het groene slotje naast de url is het met gelukt om het verkeer tussen client en server te versleutelen. Ik heb hiervoor gebruik gemaakt van een certificaat van Let's Encrypt. Let's Encrypt is een Certificate Authority die een manier biedt om programmaticaal certificaten aan te vragen en meteen te kunnen gebruiken. Een enorm bijkomend voordeel is dat ze deze service gratis aanbieden. Let's Encrypt biedt een software client die het nog makkelijker maakt om zo'n certificate aan te vragen; letsencrypt.

Ik draai de app op een Ubuntu 16.04 server met daarover Nginx om een reverse proxy op de port van de Express app te zetten.

Ik heb Nginx zo geconfigureerd dat hij standaard alle requests die binnenkomen via HTTP (op port 80) worden ge-redirect naar de beveiligde SSL verbinding op 443.

Diffie-Hellman key exchange

Naast alleen het toevoegen van een certificaat kun je je encryptie te verbeteren door je Diffie-Hellman Group te versterken. Met deze groep wordt de eerste communicatie tussen client en server gecheckt en versleuteld, wat man-in-the-middle-attacks doet voorkomen. Een goeie korte uitleg over het basis principe is te vinden op, jawel, Wikipedia.

HTTP Strict Transport Security (HSTS)

HSTS is een opt-in beveilingsmaatregel waarmee een webserver aan een browser kan laten weten alleen de beveiligde verbinding te vertrouwen. Zodra een browser die deze functie ondersteund deze melding krijgt (via een response header), zal de browser voorkomen dat er communicatie plaatsvindt over HTTP en zal standaard alle requests over HTTPS blijven sturen. Een aantal voorbeelden waarbij dit de beveiliging helpt:

  • HSTS verandert alle HTTP requests naar HTTPS requests (net als Nginx, maar dan client-side al)
  • HSTS verandert automatisch alle urls naar externe bronnen naar HTTPS
  • HSTS voorkomt dat tussenpersonen het certificaat kunnen overschrijven

Resultaat