Het onlangs gevonden lek in Ruby on Rails is gevaarlijk voor iedereen die dit platform gebruikt, niet alleen voor DigiD. Het lek zit immers niet in de code die voor DigiD is gemaakt, maar in het onderliggende platform, Rails. Ruby is de programmeertaal waarin Rails is geschreven, en heeft dus eigenlijk niets te maken met het lek. Het is interessant om te zien hoe dit lek kon ontstaan, omdat vrijwel alle webapplicatieplatformen dit soort lekken hebben gehad, of misschien nog hebben of gaan krijgen.
Het zwakke punt in dergelijke platformen is het gebruik van gegevens die van de gebruiker van de website komen. Deze parameters zijn natuurlijk belangrijk voor het functioneren van een website, denk bijvoorbeeld aan het invoeren van een gebruikersnaam en wachtwoord, een adres, of een locatie. De parameters die van de gebruiker komen worden meestal gebruikt om gegevens in een database op te vragen of te veranderen. Dit gaat via sql-opdrachten, waarin de parameters worden ingevuld. Neem bijvoorbeeld:
“SELECT * FROM users WHERE name = ‘” + userName + “‘;”
waarbij userName de door de gebruiker aangeleverd parameter bevat. Door een ‘vreemde’ gebruikersnaam op te geven (bijvoorbeeld ‘ or ‘1’=‘1) kan de sql-opdracht worden veranderd, zoals uitgelegd op de Wikipedia-pagina over sql-injectie. Op deze manier is het eenvoudig om allerlei gegevens uit de database te halen.
De meeste websites zijn wel beveiligd tegen simpele sql-injectie, omdat ‘vreemde’ parameters die de sql-opdrachten veranderen, worden tegengehouden. Maar een simpele zoekopdracht op Google naar “inurl:select inurl:where inurl:%20” geeft nog altijd een handjevol websites die duidelijk niet beveiligd zijn.
Natuurlijk biedt een platform als Rails beveiliging tegen sql-injectie. Het probleem is echter dat er heel veel types parameters zijn. Denk aan namen, getallen, datums, maar ook webservice-aanroepen en xml-documenten. Daarnaast worden deze parameters ook nog eens op verschillende manieren gecodeerd en gedecodeerd. Door alle verschillende representaties, coderingen en omzettingen is het behandelen van parameters een complexe aangelegenheid. Een webframework neemt de meeste decoderingen en typeomzettingen voor zijn rekening, maar vaak moet de programmeur aangeven welke omzettingen en filters toegestaan zijn.
Kwaadwillenden kunnen zelfs een simpel invoerveld in een webpagina misbruiken om sql, en in het geval van het Rails-lek ook Ruby-code, te ‘injecteren’ in een webapplicatie. Het Rails-lek ontstond, omdat bij het decoderen van parameters een automatische conversie plaatsvond naar het juiste datatype. Wanneer een parameter zelf aangaf dat deze de YAML, een variant van xml om gegevens te coderen, representatie gebruikte, ging Rails deze automatisch omzetten naar een interne gegevensstructuur. Gestructureerde xml- en YAML-documenten bevatten echter verwijzingen naar interne en externe gegevens, en daarmee was het mogelijk om code te injecteren.
Door de complexiteit van conversies is het heel moeilijk geworden om gebruikersparameters te controleren. Het is bijvoorbeeld niet voldoende om te controleren of een xml-document dat van buiten komt geen (sql- of Ruby-) code bevat. Ook zonder dergelijke code is het simpel om een denial of service-aanval uit te voeren.
Betekent dit nu dat we voor belangrijke applicaties niet meer moeten vertrouwen op platforms zoals Rails, en alle lagen van een applicatie zelf moeten bouwen? Dat lijkt mij niet. Hoewel de beveiliging van Rails niet 100 procent waterdicht bleek te zijn, is deze op een niveau dat een softwareontwikkelteam niet snel zal evenaren. Er zijn zoveel aanvalsmogelijkheden dat deze alleen voor experts is te overzien. Rails wordt door veel websites gebruikt, waardoor dit lek belangrijk en urgent was. Omdat Rails open source is, kennen veel mensen de programmacode en kon het lek snel worden gedicht. De meeste lekken in ‘eigenbouw’-oplossingen worden waarschijnlijk nooit gevonden, behalve door mensen die ernaar op zoek zijn met kwade bedoelingen.