Wie mag wat: in de praktijk
Je controle uit les 3 koppelt een bericht aan een account. Een echte site doet dat ook, maar daar mogen sommige mensen meer dan anderen, en zijn er honderden endpoints. Het idee blijft hetzelfde: elk endpoint vraagt zelf wie dit mag.
Wat jij zelf doet
Standaard: nee
Een endpoint zonder controle staat open. Daarom begin je bij elk nieuw endpoint met de vraag wie het mag, en schrijf je die controle als eerste, vóór de rest. Dat heet deny by default: wat je niet uitdrukkelijk toestaat, mag niet.
In een groter project schrijf je de controle niet in elk endpoint opnieuw.
FastAPI heeft daar Depends voor, dat deze cursus niet behandelt: één functie
die de ingelogde gebruiker ophaalt, en die FastAPI aanroept vóór elk endpoint
waaraan je hem koppelt. Vergeet je hem
bij één endpoint, dan staat dat endpoint open, dus ook dan loop je ze langs.
Test het als de ander
Je script uit les 2 is een test: het doet alsof het
Alex is en kijkt of de server weigert. Echte projecten draaien zulke tests
automatisch, bij elke wijziging. Per endpoint zijn er dan twee: de
eigenaar krijgt 200, een ander 403; Alles wissen uit les 5 is de
uitzondering. Breekt iemand later per ongeluk de controle, dan valt de tweede
test om voordat het op de site staat.
Wat grote sites nog meer doen
Dit hoef je voor je eigen project niet te bouwen. Klap open wat je wilt lezen.
Een naam voor deze zwakheid
Wat Alex deed, heet broken access control: de toegang is niet goed geregeld. Het geval waarin je met een andere sleutel of een ander nummer bij iets van een ander komt, heeft een eigen naam: IDOR, Insecure Direct Object Reference. Broken access control staat bovenaan de bekendste lijst van zwakheden die in webapplicaties het vaakst gevonden worden.
Dat het zo vaak voorkomt, komt doordat alles werkt zolang iedereen de knoppen gebruikt. Het valt pas op als iemand een verzoek zelf verstuurt.
Een vast nummer in plaats van een naam
Je gastenboek koppelt een bericht aan de naam van een account. Dat gaat goed zolang een naam nooit verandert. Mag iemand zijn naam wijzigen, dan zijn zijn oude berichten van niemand meer, of van wie die naam daarna kiest. Grote sites geven daarom elk account een vast nummer dat nooit verandert, en zetten dat nummer bij elk bericht. De naam is dan alleen wat je op het scherm ziet.
De controle blijft hetzelfde: het nummer in de sessie en het nummer bij het bericht heeft de server allebei zelf vastgelegd, nadat het wachtwoord klopte.
Beheerders
Op de meeste sites mag iemand meer dan de rest: een moderator verwijdert berichten van anderen, een docent ziet alle inleveringen. Dat heet een rol. In de controle wordt dat één voorwaarde erbij:
BEHEERDERS = {"Sara"}
ingelogd = mijn.get("naam")
if bericht["naam"] != ingelogd and ingelogd not in BEHEERDERS:
raise HTTPException(status_code=403, detail="Dit is niet jouw bericht")
Grote sites bewaren rollen in de database en geven ze per onderdeel: iemand kan beheerder zijn van één forum en gewone bezoeker van de rest.
Een lange sleutel is geen slot
Heb je opdracht 5 van Een 404 sturen
gemaakt, dan heeft je gastenboek /bericht-nummer/12. Zo'n nummer is makkelijk
te raden: wie bericht 12 ziet, probeert 13. Je sleutels uit time.time_ns()
zijn lang, maar niet willekeurig: het is de tijd in nanoseconden, dus wie weet
wanneer een bericht geplaatst is, zit er dichtbij. Veel sites gebruiken daarom
lange, willekeurige sleutels, zoals je sessie-id uit secrets.token_hex. Maar
zoals je in les 2 zag, staat een sleutel vaak in de pagina. Een sleutel die niemand raadt is een extra drempel, geen vervanging van
de controle.
De wet
Bij gegevens van een ander komen via een gat in een site is in Nederland strafbaar. Het Wetboek van Strafrecht noemt het computervredebreuk (artikel 138ab): opzettelijk en zonder recht binnendringen in een computer of website. Een ander nummer in de adresbalk typen om bij andermans gegevens te komen, kan daar al onder vallen. Iets van een ander wissen of veranderen is bovendien apart strafbaar (artikel 350a). Daarom deed je de test alleen op je eigen server, met je eigen Sara en Alex.
Kom je per ongeluk een gat tegen op een site van een ander, meld het dan. Veel organisaties hebben een pagina om een kwetsbaarheid te melden; dat heet CVD, Coordinated Vulnerability Disclosure. Kijk niet verder dan nodig om het gat te zien, verander of verwijder niets, en vertel het niemand anders voordat het dicht is. Het Openbaar Ministerie houdt er rekening mee als iemand zich zo aan de regels van de organisatie houdt.
Opdracht: welke maatregel helpt?
Hieronder staan vier situaties. Kies bij elke situatie de maatregel uit deze les die het meest helpt.
- Een leerling ziet de cijfers van een klasgenoot door in de adresbalk
/cijfers/1043te veranderen in/cijfers/1044. - Een moderator moet scheldberichten van iedereen kunnen weghalen.
- Een nieuw endpoint
/profiel/wijzigwerkt, maar niemand heeft gecontroleerd wie het mag gebruiken. - Iemand verwijdert bij een ander een bericht door in het formulier diens naam in te vullen.
Antwoord
- Een controle in het endpoint: horen deze cijfers bij de ingelogde leerling?
Een lange sleutel in plaats van
1044maakt het moeilijker, maar is geen slot. - Een rol: moderators staan in de lijst met beheerders, en de controle laat hen ook door.
- Standaard nee, en een test als de ander: begin met de controle, en laat een
test als een andere gebruiker
403verwachten. - Controleer op wat de server zelf weet, zoals de ingelogde naam uit de sessie, niet op een naam uit het formulier.
Door naar de volgende reeks: Cookies afschermen.