Beste,
Ik ben bezig met een 2FA systeem.
Misschien kent u dat wel van Google Authenticator. Dat een gebruiker dat wil inloggen, eerst een email krijgt waar een code in staat en vervolgens die code moet invoeren om uiteindelijk in te kunnen loggen.
Nu ben ik bezig met zo'n systeem, maar ik wil geen externe API'S gebruiken. (Bijv. Google Authenticator)
In plaats daarvan wil ik een eigen systeem maken.
Maar hoe zal ik dit het best aanpakken?
Een token genereren natuurlijk, met $token = random_bytes(5).
En een verloopdatum met $expires = date(U) + 300;
Zijn er nog extra kolommen die ik moet toevoegen in de MYSQLI database, om de veiligheid van dit systeem te verbeteren, of nog andere (veiligheids)suggesties?

Alvast bedankt,
Up-to-date SSL-certificaat.
Ja oké, dat heb ik.
Maar nog iets anders?
(SSL = Let's Encrypt)
Je zou nog bij kunnen houden hoe vaak iemand al geprobeerd heeft om de code ($token) in te voeren. Na 3x "Helaas, U bent af. Genereer een nieuwe code en probeer het opnieuw.". En misschien nog een time-out tussen de pogingen (= tijdstip laatste poging opslaan).

Je zou alle data ook gewoon in de sessie op kunnen slaan. Dan is een kleine extra check dat ze in de aanvragende sessie zitten (en niet klaarzitten in een andere sessie om de 2FA code in te toetsen). Maar omdat je toch een vrij korte time-out hebt, en zal de sessie toch nog wel bestaan. Scheelt je weer gedoe in de database. Dit is alleen niet handig als je de code in een mailtje stuurt, met daarin een link om de code te valideren (misschien opent de link in een andere browser dan de gebruiker op dat moment zit - veel mensen hebben IE als "standaard browser", maar doen alles in Chrome).

[size=xsmall]Toevoeging op 08/03/2019 20:58:53:[/size]

O, en session_regenerate_id() na een succesvolle invoer.
Zorg na een succesvolle login dat iemand browser fingerprint van zijn device opgeslagen wordt, zodat de 2FA niet continu wordt gevraagd. Waaronder een IP-adres.

En zorg voor uitgebreide mogelijkheden om inlogsessies te kunnen beheren, en dat je de gebruiker een andere sessie kan laten uitloggen.
IP blijft tricky: gebruikers die in beweging zijn gaan van Wifi naar 4G naar WiFi enz, en krijgen steeds een ander IP-adres.

Ook UserAgent string kan wijzigen, bijvoorbeeld als iemand tussen aanvragen 2FA code en invoeren een browser update door z'n strot kreeg (dan is het versienummer in de UA-string gewijzigd).
Mja maar wat is dan wel een oplossing? Kan niet het MAC-adres van iemand zijn netwerkkaart verkrijgen :p. Op den duur zul je aannames moeten doen.
Je zou gewoon een random code in cookie/localStorage/sessionStorage op kunnen slaan. Komt die code nog steeds overeen met wat je server-side ook hebt, dan is er geen reden om een nieuwe 2FA te doen.
Hoi,

Ik zou je adviseren TOTP (https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm) zelf te implementeren.

Als je wat rond zoekt zijn er al veel github projecten te vinden met een implementatie daarvan. Als best practice wordt btw aangeraden op -1 ook goed te keuren, zodat als je code eigenlijk elke 30 seconden veranderd je ook die van tot 1 minuut geleden accepteert.

Om niet telkens iemand lastig te vallen zou ik een zogenaamde 'Trusted devices' lijst gaan bijhouden. Logt iemand in met zo'n device dan doe je geen 2FA voor de komende X dagen (vaak 30 dagen). Daarna moet de persoon weer op dat device ook een 2FA doen.
De lijst is iets van:
- user_id
- device_token
- last_2fa
En dan wat velden voor informatie die je wilt tonen aan de gebruiker. Vaak iets van:
- device_browser
- device_os
- device_initial_ip

De device_token sla je op in een cookie (secure en httpOnly).
Localstorage/sessionstorages etc. zou ik niet gebruiken. Niet alle browsers en mobile telefoons kunnen er mee overweg. Het is altijd JS en er zijn nog veel meer nadelen te benoemen.

Voordeel van zo'n lijst is dat je mensen die ook kan laten inzien en devices kan laten verdwijnen.
Rob Doemaarwat op 08/03/2019 21:35:45

IP blijft tricky: gebruikers die in beweging zijn gaan van Wifi naar 4G naar WiFi enz, en krijgen steeds een ander IP-adres.

Ook UserAgent string kan wijzigen, bijvoorbeeld als iemand tussen aanvragen 2FA code en invoeren een browser update door z'n strot kreeg (dan is het versienummer in de UA-string gewijzigd).

Daar heb je gelijk in, maar hoe zou facebook dat dan doen?


Geen idee. Wat ik wel weet is dat Twitter (die ik standaard in een "privacy" scherm open - ivm alle links naar externe sites) elke keer als ik de browser start 2FA doet/vraagt. Die slaat dus geen "device fingerprint" op maar gewoon iets van een cookie/storage (die dus steeds verdwijnt als ik de browser/computer herstart).

Reageren