Meerfactorauthenticatie wordt niet afgedwongen
CWE-308CWE-287OWASP A07:2021Bijgewerkt 3 september 20265 min leestijd
Een applicatie die tweefactorauthenticatie aanbiedt maar niet verplicht stelt, beschermt in de praktijk alleen de gebruikers die er zelf aan denken. Dat is een kleine minderheid, en zelden de accounts met de meeste rechten. Ook een MFA die alleen in de webinterface wordt afgedwongen en niet op de API, is feitelijk optioneel.
Tweefactorauthenticatie aanbieden en tweefactorauthenticatie afdwingen zijn twee heel verschillende maatregelen, met heel verschillende resultaten. Het eerste staat goed in de documentatie; het tweede beschermt uw gebruikers. Hieronder leest u waarom de vrijwillige variant zo weinig oplevert en hoe u de verplichting invoert zonder dat het een storing wordt.
Wat betekent “niet afgedwongen”?
Meerfactorauthenticatie die niet wordt afgedwongen, is een tweede factor die de applicatie ondersteunt maar niet verplicht stelt. Gebruikers kunnen hem inschakelen; ze hoeven het niet. De functionaliteit is aanwezig, de bescherming is optioneel.
Er zijn drie verschijningsvormen die in de praktijk allemaal op hetzelfde neerkomen. De eerste is de zuiver optionele variant, verstopt in een instellingenscherm dat weinig gebruikers ooit openen. De tweede is de variant die voor gewone gebruikers verplicht is maar niet voor beheerders, omdat die “er toch verstand van hebben”, terwijl juist die accounts de meeste rechten dragen. De derde is de variant die in de webinterface wordt afgedwongen maar niet op de API, waardoor de verplichting met één ander endpoint te omzeilen is.
Vergelijk het met een gebouw waar bezoekers zich mogen legitimeren als ze dat willen. De maatregel bestaat, er is een balie, er is een procedure. Alleen bepaalt de bezoeker of hij eraan meedoet, en dat is nu precies de verkeerde partij om die keuze aan te laten.
Hoe omzeilt een aanvaller optionele MFA?
Kwetsbaar:
app.post('/inloggen', async (req, res) => {
const gebruiker = await controleerInloggegevens(req.body);
if (!gebruiker) return res.status(401).send('Onjuiste gegevens');
if (gebruiker.mfaActief) { // alleen als de gebruiker het wilde
req.session.tweedeFactorVoor = gebruiker.id;
return res.redirect('/inloggen/verificatie');
}
req.session.userId = gebruiker.id; // anders meteen binnen
res.send('Welkom');
});
// De API kent die stap helemaal niet
app.post('/api/token', async (req, res) => {
const gebruiker = await controleerInloggegevens(req.body);
if (!gebruiker) return res.sendStatus(401);
res.json({ token: maakToken(gebruiker) });
});
Twee problemen tegelijk. De verificatie hangt af van een instelling die de gebruiker zelf moet hebben aangezet, en het tweede endpoint slaat de stap volledig over. Zelfs een gebruiker die MFA netjes heeft ingeschakeld, is via /api/token te benaderen met alleen een wachtwoord:
POST /api/token HTTP/1.1
Content-Type: application/json
{"email":"beheerder@bedrijf.nl","wachtwoord":"<uit een eerder datalek>"}
HTTP/1.1 200 OK
{"token":"eyJhbGciOiJIUzI1NiIs..."}
De hele maatregel is omzeild met een verzoek naar een ander adres.
Veilig:
// Eén plek waar wordt bepaald of iemand een sessie krijgt
async function magSessieKrijgen(gebruiker, req) {
const verplicht = gebruiker.rol === 'beheerder'
|| gebruiker.rol === 'financieel'
|| BELEID.mfaVoorIedereen;
if (!gebruiker.mfaActief && verplicht) return { status: 'instellen-vereist' };
if (gebruiker.mfaActief) return { status: 'verificatie-vereist' };
return { status: 'ok' };
}
app.post('/inloggen', async (req, res) => {
const gebruiker = await controleerInloggegevens(req.body);
if (!gebruiker) return res.status(401).send('Onjuiste gegevens');
const { status } = await magSessieKrijgen(gebruiker, req);
if (status === 'instellen-vereist') {
req.session.mfaInstellenVoor = gebruiker.id; // beperkte toestand
return res.redirect('/mfa/instellen');
}
if (status === 'verificatie-vereist') {
req.session.tweedeFactorVoor = gebruiker.id;
return res.redirect('/inloggen/verificatie');
}
req.session.regenerate(() => { req.session.userId = gebruiker.id; res.send('Welkom'); });
});
Het bepalende verschil is dat er nog maar één plek is waar wordt beslist of iemand een sessie krijgt, en dat elk kanaal (webinterface, API, mobiele applicatie) daar doorheen gaat. Een gebruiker voor wie MFA verplicht is maar die het nog niet heeft ingesteld, komt in een beperkte toestand terecht waarin hij alleen dat kan regelen.
Wat is de impact van niet-afgedwongen MFA?
De ernst is middelzwaar tot hoog en hangt af van welke accounts onbeschermd blijven. In de praktijk is dat een ongunstige selectie: gebruikers die MFA vrijwillig inschakelen zijn doorgaans de meer bewuste gebruikers, terwijl de accounts die het meeste risico dragen vaak juist die van drukke leidinggevenden en beheerders zijn.
Het gevolg is dat u de maatregel wel hebt maar de bescherming niet. Bij een aanval met inloggegevens uit een eerder datalek maakt het niet uit hoeveel procent van uw gebruikers een tweede factor heeft; het maakt uit of het account dat de aanvaller raakt er een had. Bij duizenden geautomatiseerde pogingen is dat een kwestie van statistiek.
Er is ook een organisatorisch effect dat zwaarder weegt dan het technische. Een optionele maatregel geeft de organisatie het gevoel dat MFA “geregeld” is. In audits, in rapportages en in gesprekken met klanten wordt dat ook zo gepresenteerd. Het verschil tussen beschikbaar en verplicht blijft daarbij vaak onbenoemd, waardoor het risico onzichtbaar wordt in plaats van opgelost.
Hoe spoor je niet-afgedwongen MFA op?
Een tester kijkt eerst of MFA beschikbaar is en of het verplicht wordt gesteld, en voor welke rollen. Vervolgens wordt geprobeerd of de verplichting te omzeilen is.
Dat gebeurt langs een aantal vaste routes. Kan een account met MFA ingeschakeld toch een sessie of token krijgen via de API, via een oudere API-versie of via een mobiel eindpunt? Kan het verificatiescherm worden overgeslagen door na de wachtwoordstap rechtstreeks een beschermde route aan te roepen? Is er een “onthoud dit apparaat”-functie die de verificatie langdurig overslaat, en is die aan het apparaat gebonden? Werkt de wachtwoordherstelroute zonder tweede factor, waarmee de hele maatregel via een omweg vervalt? AssistSec test daarnaast expliciet de accounts met de hoogste rechten, omdat een uitzondering voor beheerders het vaakst voorkomt en tegelijk het zwaarste weegt.
Hoe voorkom je niet-afgedwongen MFA?
- Maak meerfactorauthenticatie verplicht voor beheerders en voor rollen met toegang tot gevoelige gegevens.
- Voer de verplichting gefaseerd in met een aankondiging, een uitsteltermijn en een instelscherm na inloggen.
- Bepaal op één centrale plek of iemand een sessie krijgt, zodat elk kanaal dezelfde regels volgt.
- Dwing de verificatie af op de API, op mobiele eindpunten en op oudere versies, niet alleen in de webinterface.
- Sluit verouderde protocollen en integraties af die authenticatie zonder tweede factor toestaan.
- Bind een “onthoud dit apparaat”-functie aan het apparaat, geef hem een beperkte looptijd en maak hem intrekbaar.
- Vraag ook bij wachtwoordherstel om de tweede factor, zodat die route geen omweg wordt.
- Registreer uitzonderingen met een einddatum en beperk de rechten van die accounts.
- Rapporteer periodiek welk deel van de accounts daadwerkelijk een tweede factor gebruikt, uitgesplitst naar rol.
Bronnen
Veelgestelde vragen
Hoe voer ik een verplichting in zonder gebruikers buiten te sluiten?
Gefaseerd. Begin met beheerders en gevoelige rollen, kondig de wijziging aan met een termijn, en toon na inloggen een scherm dat vraagt om instelling met de mogelijkheid om een aantal keer uit te stellen. Maak het daarna verplicht. Zo verschuift de last naar het moment van instellen in plaats van naar het moment van buitensluiting.
Waarom is de API zo vaak de zwakke plek?
Omdat de tweede factor in de webinterface wordt afgedwongen en de API met dezelfde inloggegevens tokens uitgeeft zonder die stap. De verplichting is dan omzeilbaar door simpelweg een ander endpoint te gebruiken. Dwing de verificatie af op de plek waar de sessie ontstaat, niet in de interface.
Moet ik MFA voor alle gebruikers verplichten?
Voor beheerders en rollen met toegang tot gevoelige gegevens zonder uitzondering. Voor gewone gebruikers hangt het af van uw doelgroep en van wat er achter het account zit. Bied het in elk geval standaard ingeschakeld aan, zodat uitschakelen een bewuste keuze is in plaats van instellen.
Wat doe ik met accounts die het niet kunnen gebruiken?
Behandel uitzonderingen als uitzonderingen: registreer ze, geef ze een einddatum en beperk hun rechten. Een permanente uitzonderingenlijst die niemand meer beoordeelt, is precies de omweg die een aanvaller zoekt.
Verwante artikelen
- KwetsbaarhedenCWE-287A07:2021Broken authenticationBroken authentication uitgelegd: hoe aanvallers via brute force, gelekte wachtwoorden en voorspelbare sessietokens accounts overnemen, en wat u eraan doet.
- KwetsbaarhedenCWE-307A07:2021Brute force en credential stuffingBrute force en credential stuffing uitgelegd: hoe aanvallers wachtwoorden raden of gelekte inloggegevens hergebruiken, en hoe throttling en MFA dat stoppen.
- KwetsbaarhedenCWE-306A07:2021Meerfactorauthenticatie uitschakelen zonder verificatieEen tweede factor die met één klik kan worden uitgezet, beschermt alleen tegen aanvallers die daar niet aan denken. Lees hoe u dat afdekt.
- KwetsbaarhedenCWE-308A07:2021Meerfactorauthenticatie ontbreektZonder tweede factor is een gelekt wachtwoord genoeg voor volledige toegang. Lees welke MFA-vormen bescherming bieden en welke niet.
- KwetsbaarhedenCWE-521A07:2021Zwakke eisen aan wachtwoordenComplexiteitsregels leveren zwakkere wachtwoorden op dan lengte en een blokkadelijst. Lees welke eisen wél werken volgens de huidige richtlijnen.