Direct naar inhoud

Broken authentication

CWE-287OWASP A07:2021Bijgewerkt 29 augustus 20265 min leestijd

Broken authentication is een verzamelnaam voor fouten in inloggen en sessiebeheer waardoor een aanvaller zich als een andere gebruiker kan voordoen. Denk aan brute force zonder limiet, onveilige wachtwoordopslag of voorspelbare sessietokens. De oplossing combineert MFA, sterke wachtwoordhashing en degelijk sessiebeheer.

Het inlogscherm is de voordeur van uw applicatie, en juist die voordeur blijkt in de praktijk vaak de zwakste plek. Broken authentication staat als Identification and Authentication Failures in de OWASP Top 10 en omvat alle manieren waarop aanvallers de identiteitscontrole omzeilen, van brute force tot vervalste sessies. Hieronder leest u hoe zulke aanvallen verlopen en hoe u inloggen en sessiebeheer wél op orde krijgt.

Wat is broken authentication?

Broken authentication is de verzamelnaam voor kwetsbaarheden in de manier waarop een applicatie vaststelt wie er inlogt én hoe zij die ingelogde status daarna bewaakt. Het gaat dus niet om één specifieke fout, maar om een familie: zwakke wachtwoordeisen, onveilige wachtwoordopslag, inlogformulieren zonder rem op het aantal pogingen, voorspelbare sessietokens en slordige herstelflows voor vergeten wachtwoorden. In alle varianten is de uitkomst gelijk: iemand krijgt toegang tot een account dat niet van hem is.

Een alledaagse vergelijking: een hotel waar de receptionist een kamersleutel meegeeft aan iedereen die een kamernummer noemt, zonder ooit legitimatie te vragen. Of een hotel dat wél controleert, maar sleutelkaarten uitgeeft met opeenvolgende nummers: wie kaart 214 heeft, weet hoe 215 eruitziet. In beide gevallen is niet het slot kapot, maar het proces eromheen.

Belangrijk om te beseffen: authenticatie is breder dan het inlogformulier alleen. Ook wachtwoordopslag, sessiebeheer, onthoud-mij-cookies, API-sleutels en de wachtwoord-reset horen bij dezelfde keten, en een aanvaller zoekt altijd de zwakste schakel.

Hoe werkt een aanval op authenticatie?

Aanvallers hoeven zelden iets te kraken; meestal gebruiken ze de voordeur zoals hij is gebouwd. Bij credential stuffing proberen ze gelekte e-mail-wachtwoordcombinaties uit eerdere datalekken geautomatiseerd uit. Bij brute force laten ze een script duizenden wachtwoorden per minuut afvuren. En als de applicatie zelf zwakke tokens uitdeelt, slaan ze het raden zelfs over. Het voorbeeld hieronder is een login-endpoint dat drie klassieke fouten combineert.

Kwetsbaar:

// Wachtwoord in platte tekst, pratende foutmeldingen, voorspelbaar token
app.post("/login", async (req, res) => {
  const user = await db.findUserByEmail(req.body.email);
  if (!user) {
    return res.status(401).send("Onbekend e-mailadres");
  }
  if (user.password !== req.body.password) {
    return res.status(401).send("Wachtwoord onjuist");
  }

  // "Sessietoken": Base64 van het gebruikers-id
  const token = Buffer.from("user:" + user.id).toString("base64");
  res.cookie("session", token);
  res.send("Ingelogd");
});

Er gaat hier van alles mis tegelijk. De twee verschillende foutmeldingen verraden of een e-mailadres bestaat (user enumeration), waardoor een aanvaller eerst een lijst geldige accounts opbouwt en daarna gericht gelekte wachtwoorden test. Een limiet op het aantal pogingen ontbreekt, dus dat testen mag eindeloos doorgaan. Het wachtwoord staat bovendien in platte tekst in de database. Eén datalek en elk wachtwoord ligt op straat. De ernstigste fout is echter het sessietoken: Base64 is geen encryptie maar een codering die iedereen kan omkeren. Een aanvaller codeert zelf de tekst user:1, plakt de uitkomst dXNlcjox in zijn cookie en is ingelogd als gebruiker 1, vaak een beheerder, zonder ooit een wachtwoord te hoeven kennen.

De veilige variant repareert alle drie de zwaktes: wachtwoorden worden als hash vergeleken, de foutmelding verklapt niets, het aantal pogingen is begrensd en het sessietoken komt uit een cryptografisch veilige generator.

Veilig:

// Hash-vergelijking, generieke foutmelding, limiet, willekeurig token
app.post("/login", loginRateLimiter, async (req, res) => {
  const user = await db.findUserByEmail(req.body.email);
  const hash = user ? user.passwordHash : DUMMY_HASH;
  const valid = await bcrypt.compare(req.body.password, hash);

  if (!user || !valid) {
    return res.status(401).send("Ongeldige inloggegevens");
  }

  // Sessietoken: 32 willekeurige bytes, server-side opgeslagen
  const sessionId = crypto.randomBytes(32).toString("hex");
  await sessions.create(sessionId, user.id);
  res.cookie("session", sessionId, {
    httpOnly: true,
    secure: true,
    sameSite: "lax",
  });
  res.send("Ingelogd");
});

Let op het detail met DUMMY_HASH: ook als het account niet bestaat, voert de code een hash-vergelijking uit. Zo duurt elke inlogpoging even lang en valt uit de reactietijd niet af te leiden welke e-mailadressen bestaan. Het sessietoken is nu 256 bits toeval dat alleen server-side aan een gebruiker gekoppeld is; raden of terugrekenen is kansloos. De cookie-vlaggen zorgen er ten slotte voor dat scripts en afluisteraars niet bij het token kunnen.

De wachtwoord-vergeten-functie is een tweede voordeur. Een resetlink die lang geldig blijft, vaker dan één keer werkt of een voorspelbaar token bevat, maakt alle andere maatregelen waardeloos. Behandel resettokens net zo streng als wachtwoorden: willekeurig, kort geldig en eenmalig.

Wat is de impact van broken authentication?

De directe schade is accountovername. Een aanvaller die als klant inlogt, ziet persoonsgegevens, bestelhistorie en opgeslagen betaalmethoden, en kan namens het slachtoffer handelen. Gaat het om een beheerdersaccount, dan verschuift de impact van één account naar de hele applicatie: alle gebruikersgegevens, alle instellingen, vaak ook een opstap naar de onderliggende infrastructuur.

Op schaal wordt het een bedrijfsrisico. Credential stuffing is goedkoop te automatiseren, dus één zwak inlogformulier kan binnen dagen duizenden overgenomen accounts opleveren, met fraude, chargebacks en een meldplichtig datalek onder de AVG als gevolg. Reputatieschade komt daar nog bovenop: gebruikers vergeven een gehackt account zelden.

Extra verraderlijk is dat deze aanvallen nauwelijks opvallen. Een gekaapte sessie of een geslaagde credential-stuffing-login ziet er in de logs uit als een gewone gebruiker die inlogt. Omdat de gevolgen uiteenlopen van één overgenomen account tot volledige compromittering van de applicatie, loopt de ernst van hoog tot kritiek.

Hoe spoort u broken authentication op?

Testers beginnen bij wat de applicatie prijsgeeft: verschillen in foutmeldingen of reactietijden die verraden welke accounts bestaan. Daarna volgt de rem op pogingen: accepteert het formulier honderden wachtwoorden achter elkaar zonder blokkade of vertraging? Ook sessietokens worden onderzocht: door er tientallen te verzamelen en te analyseren op patronen, lengte en voorspelbaarheid. Tot slot de levenscyclus: blijft een sessie geldig na uitloggen of na een wachtwoordwijziging, en hoe streng is de herstelflow?

Geautomatiseerde scanners vangen hooguit de oppervlakkige signalen; de logica erachter vergt handwerk. Dit is bij uitstek een onderdeel dat AssistSec tijdens een penetratietest systematisch doorloopt, van tokenanalyse tot resetflow, zodat u precies weet via welke route een aanvaller daadwerkelijk bij een account komt.

Hoe voorkomt u broken authentication?

  • Schakel multi-factor authenticatie (MFA) in, minimaal voor beheerders. Een gelekt of geraden wachtwoord is dan niet langer genoeg.
  • Sla wachtwoorden op als hash met bcrypt, scrypt of Argon2, nooit in platte tekst en nooit met snelle hashes zoals MD5 of SHA-1.
  • Begrens inlogpogingen met rate limiting, oplopende vertraging of een tijdelijke blokkade per account én per IP-adres.
  • Houd foutmeldingen generiek, ongeacht of het e-mailadres bestaat, en houd ook de reactietijd gelijk.
  • Genereer sessietokens met een cryptografisch veilige generator, bewaar ze server-side en geef cookies de vlaggen httpOnly, secure en sameSite mee.
  • Vernieuw het sessietoken direct na inloggen en maak alle sessies ongeldig bij uitloggen en na een wachtwoordwijziging.
  • Maak resettokens eenmalig en kort geldig en bevestig gevoelige wijzigingen via een tweede kanaal.
  • Toets nieuwe wachtwoorden aan lijsten met gelekte wachtwoorden in plaats van alleen op complexiteitsregels te vertrouwen.
  • Laat de hele authenticatieketen periodiek testen, inclusief sessiebeheer en herstelflows. Daar zitten de fouten die scanners missen.

Bronnen

Veelgestelde vragen

Wat valt er allemaal onder broken authentication?

Alle fouten waarmee een aanvaller zich als iemand anders kan voordoen: zwakke of gelekte wachtwoorden, brute force zonder limiet, onveilige wachtwoordopslag, voorspelbare sessietokens en kwetsbare herstelflows voor vergeten wachtwoorden.

Wat is credential stuffing?

Een aanval waarbij gelekte combinaties van e-mailadres en wachtwoord uit eerdere datalekken geautomatiseerd op andere sites worden geprobeerd. Omdat veel mensen wachtwoorden hergebruiken, slaagt steevast een klein maar winstgevend percentage.

Is een streng wachtwoordbeleid voldoende?

Nee. Complexiteitsregels helpen weinig tegen hergebruikte of gelekte wachtwoorden en niets tegen zwak sessiebeheer. Combineer een goed beleid met MFA, rate limiting en veilige sessietokens.

Helpt MFA tegen broken authentication?

Het is de effectiefste losse maatregel: een gestolen of geraden wachtwoord is dan niet meer genoeg om in te loggen. MFA beschermt alleen niet tegen fouten in sessiebeheer, dus ook die basis moet op orde zijn.

Verwante artikelen

Druk op / om te zoeken · Esc