“Hoe weet ik zeker dat de gegevens die ik via de app ophaal van onze server ook daadwerkelijk van die server komen?”
Een belangrijke vraag voor inmiddels elke app. In bijna alle apps zijn er wel gegevens die moeten worden opgehaald, of ze maken gebruik van een API om data veilig remote op te slaan. Daarbij is het goed om te weten dat we ook daadwerkelijk tegen die server aanpraten die we zelf hebben ingericht en/of uitgekozen. Dit om de gevolgen van een “man in the middle” (MITM) aanval te minimaliseren. Uiteraard verbinden we altijd via een SSL tunnel met de server, maar ook dan willen we kunnen valideren dat de server daadwerkelijk is wie hij zegt dat hij is. Hiervoor maken we gebruik van certificaat pinning. Dit klinkt heftig, maar is uiteindelijk erg eenvoudig en zou voor elke app de standaard moeten zijn.
Bij certificaat pinning bouwen we in de app informatie mee over het certificaat dat we verwachten. Beschikt de server niet over een certificaat met gelijke gegevens, dan weigeren we de verbinding. Voldoet hij wel, dan slaan we direct het certificaat op en zullen we in het vervolg geen andere meer accepteren dan deze. In een app weten we namelijk welke servers we zullen gaan gebruiken en weten we dus ook op voorhand wat de details van de huidige certificaten zijn (deze vallen vaak onder eigen beheer). Daarmee kunnen we dus kijken of tijdens het gebruik van de app exact dezelfde server wordt gebruikt.
Als we een connectie openen met een server over SSL, dan zijn er twee stappen op basis waarvan we het certificaat kunnen beoordelen:
Het certificaat is ondertekend door een vertrouwde CA (root certificate authority).
De naam van de server en de naam in het certificaat (CN) komen overeen.
Mochten deze twee niet kloppen, dan geeft de connectie een waarschuwing, vervolgens is het aan de app om te bepalen wat er gedaan moet worden.
Maar bij een MITM kan een ander redelijk eenvoudig deze beide checks op groen laten springen. Bijvoorbeeld door op het besturingssysteem een eigen certificaat aan de lijst met vertrouwde CA’s toe te voegen en aan de server een certificaat te geven met een zelf ingevoerde CN, welke dan ondertekend is door de net toegevoegde CA. Hiermee weet de app niet beter dan dat het certificaat vertrouwd wordt door het OS en de CN ook nog eens klopt… Dit is wat we willen voorkomen.
Om deze hack te blokkeren willen we zeker weten dat er niet met het certificaat is gerommeld. Hiervoor gaan we vooraf extra informatie in de app meegeven en wel details van het huidige certificaat. In een SSL-certificaat staan onder andere gegevens over de fabrikant, zoals naam, plaats, land e.d., maar ook een vervaldatum en de naam van de CA. Als we enkel certificaten accepteren die voldoen aan deze gegevens, dan is de kans dat er mee gerommeld is minimaal.
En dan komt nu het belangrijkste: zodra we een goed certificaat zien, slaan we deze in de app op en accepteren voortaan niet meer met de details van het certificaat, maar vergelijken we het volledige certificaat! Dan moet hij binair exact hetzelfde zijn.
Zoals iedereen weet, 100% veilig bestaat niet. Maar doordat we enkel een eerste keer de detail vergelijking doen, wordt de window-of-opportunity (WOO) zo kort mogelijk.
Er bestaat natuurlijk altijd het risico dat apps gedecompileerd worden of met een debugger voor de gek gehouden worden, maar ook daar zijn beschermingsmaatregelen voor.
Neem gerust contact met ons op! Wij reageren op werkdagen binnen 24 uur.