HAVO Informatica study materials
HAVO Informatica study resources

Inloggen bij Bakkerij Van Dijk

HAVO Informatica · Put your knowledge to work in context.

All case studies

Inloggen bij Bakkerij Van Dijk

Webwinkel Bakkerij Van Dijk heeft 1.400 klantaccounts. De site is twee jaar geleden gebouwd door een stagiair en draait op PHP met MySQL. De inlogpagina bouwt de query als volgt op: SELECT * FROM klanten WHERE email = '$email' AND wachtwoord = '$ww'. De wachtwoorden staan als platte tekst in de tabel. Vorige week typte een klant in het e-mailveld ' OR '1'='1' -- in en kwam direct binnen op het account van de eigenaar, inclusief de volledige ordergeschiedenis. De eigenaar wil drie maatregelen nemen: (1) een wachtwoordbeleid met minimaal 8 tekens, minimaal één hoofdletter, één cijfer en één leesteken, en verplicht wijzigen elke 60 dagen; (2) een captcha op het inlogformulier; (3) de functie 'wachtwoord vergeten' laten werken door het huidige wachtwoord per e-mail naar de klant te sturen, want dat kan toch omdat het leesbaar is opgeslagen. De webshop gebruikt geen tweestapsverificatie.

1. Laat zien hoe de invoer ' OR '1'='1' -- tot een geslaagde login leidt. Welke structurele maatregel voorkomt dit, en waarom is het filteren van aanhalingstekens een zwakkere oplossing?

Read the worked answer

Na invulling wordt de query:

SELECT * FROM klanten WHERE email = '' OR '1'='1' -- ' AND wachtwoord = '...'

Alles na -- is commentaar, dus de wachtwoordcontrole vervalt volledig. '1'='1' is altijd waar en email = '' filtert niets, dus de database geeft alle 1.400 rijen terug. De PHP-code pakt de eerste rij en logt in als die klant, toevallig de eigenaar omdat die als eerste is toegevoegd. De invoer werd niet als gegeven maar als code behandeld: dat is de kern van SQL-injectie.

Structurele maatregel: prepared statements met parameters. De query wordt dan één keer als vaste structuur naar de database gestuurd en de invoer gaat er als waarde aan vast; de database kan die waarde nooit als SQL uitvoeren. Bovendien hoort het wachtwoord helemaal niet in de query te staan (zie de volgende opdracht).

Waarom filteren zwakker is: je moet raden welke tekens gevaarlijk zijn. Een filter op aanhalingstekens faalt bij een getalveld zonder quotes, bij een andere tekenset of encoding, en bij fouten in de escaping. Je bestrijdt dan het symptoom in plaats van de oorzaak.

2. Leg uit waarom opslag als platte tekst een probleem is, hoe een salted hash dat oplost, en waarom de voorgestelde functie 'wachtwoord vergeten' moet verdwijnen.

Read the worked answer

Bij een datalek zijn alle 1.400 wachtwoorden meteen bruikbaar. Klanten hergebruiken wachtwoorden, dus zo'n lek raakt ook hun e-mail en bankieren. Een hashfunctie is eenrichtingsverkeer: je slaat alleen de hash op, en bij het inloggen hash je de ingetypte invoer opnieuw en vergelijkt die met de opgeslagen waarde. De database kan het wachtwoord zelf niet meer teruggeven.

Een salt is een uniek, willekeurig stuk data per gebruiker dat je samen met de hash opslaat. Twee klanten met hetzelfde wachtwoord krijgen daardoor een verschillende hash, en voorberekende tabellen (rainbow tables) zijn waardeloos. Gebruik een bewust langzame hash met instelbare werkfactor, zoals bcrypt of Argon2, en niet één keer SHA-256: dat is zo snel dat een aanvaller miljarden pogingen per seconde kan doen. Voor bestaande accounts moet iedereen een nieuw wachtwoord kiezen, omdat de oude al gelekt kunnen zijn.

'Wachtwoord vergeten' mag het wachtwoord nooit mailen: e-mail is onderweg niet versleuteld en de eigenaar van het account kan het lezen. Vervang het door een eenmalige link met een token dat na bijvoorbeeld 30 minuten verloopt, waarna de klant zelf een nieuw wachtwoord instelt.

3. Beoordeel maatregel (1) en maatregel (2). Welke maatregel neemt het grootste risico weg, en in welke volgorde zou je werken?

Read the worked answer

Maatregel (2), de captcha, helpt tegen geautomatiseerd wachtwoorden proberen (credential stuffing) en is dus nuttig, maar doet niets tegen de injectie. De aanvaller in dit verhaal had geen enkel account nodig en kwam binnen via een formulierveld.

Maatregel (1) is zwak en deels contraproductief. Acht tekens met hoofdletter, cijfer en leesteken levert voorspelbare wachtwoorden op zoals Zomer2025!, en verplicht wisselen elke 60 dagen verergert dat: gebruikers veranderen alleen het laatste cijfer. Beter is een minimale lengte van 12 tot 14 tekens zonder verplichte tekenklassen, geen geforceerde rotatie, wel een controle tegen bekende gelekte wachtwoorden, rate limiting en tweestapsverificatie.

Volgorde: eerst de injectie dichten met prepared statements en de wachtwoorden hashen, daarna het beleid en de captcha. Zonder die eerste stap is het beleid een duurdere muur om een open deur: de aanvaller komt toch binnen zonder wachtwoord. Merk ook op dat de eigenaar de captcha en het beleid als 'de oplossing' ziet, terwijl het lek dat hij zelf zag daar niets mee te maken heeft.