Mass Assignment: werking en beveiliging
Auteur: Redactie Domeny.ForSale Gepubliceerd
Kort samengevat: Mass Assignment is het automatisch toewijzen van gegevens uit een HTTP-verzoek aan velden van een intern object of databasemodel. Het wordt een beveiligingslek wanneer de applicatie zo ook velden laat wijzigen waarover de gebruiker geen controle hoort te hebben, zoals de beheerdersrol. Bescherming bestaat vooral uit het expliciet vastleggen van toegestane velden en het controleren van rechten op de server.
Hoe automatische veldtoewijzing werkt
Een webapplicatie ontvangt gegevens die de browser verstuurt, bijvoorbeeld bij het opslaan van een profiel. Een HTTP-verzoek, oftewel een bericht aan de server, kan een gebruikersnaam, e-mailadres en andere waarden bevatten. De server moet die vervolgens toewijzen aan de bijbehorende velden in de code.
Met Mass Assignment kan dat in één keer, zonder elke waarde handmatig toe te wijzen. Het mechanisme koppelt de namen van ontvangen velden aan de eigenschappen van een object. Als de gegevens een veld naam bevatten, kan de waarde daarvan terechtkomen in de eigenschap naam van het gebruikersobject.
Deze vorm van toewijzing wordt ook wel autobinding genoemd. Bij deze kwetsbaarheid kom je ook de term object injection tegen, al kan die in andere beveiligingscontexten op andere mechanismen duiden. Automatische toewijzing is op zichzelf geen fout: het probleem ontstaat wanneer de server meer velden accepteert dan zou mogen.
Eenvoudig voorbeeld: een profiel bewerken en de rol wijzigen
Stel dat je via het formulier voor profielbewerking alleen de weergavenaam en het e-mailadres kunt wijzigen. Geldige gegevens die naar de server worden verstuurd, zien er zo uit:
{
"naam": "Jan de Vries",
"email": "jan (at) example.com"
}
In de database heeft het account echter meer eigenschappen. Naast de naam en het e-mailadres bevat het ook het veld rol, dat de rechten van de gebruiker bepaalt. Het formulier toont dit veld niet, omdat een gewone gebruiker het niet mag kunnen wijzigen.
Een aanvaller hoeft het formulier echter niet te gebruiken. Die kan het verstuurde verzoek aanpassen en een extra veld toevoegen:
{
"naam": "Jan de Vries",
"email": "jan (at) example.com",
"rol": "beheerder"
}
Als de server alle ontvangen eigenschappen zonder beperkingen naar het account kopieert, kan ook de nieuwe rol worden opgeslagen. Wanneer het rechtensysteem dit veld gebruikt, kan de aanvaller daardoor beheerderstoegang krijgen.
Een veld weglaten uit het formulier is geen beveiliging. De server moet bepalen wat gewijzigd mag worden, niet de vormgeving van de pagina of de JavaScript-code die in de browser draait.
Welke gegevens extra risico lopen
Mass Assignment raakt niet alleen gebruikersaccounts. Het risico ontstaat overal waar externe gegevens automatisch worden toegewezen aan objecten die ook interne eigenschappen bevatten.
Voorbeelden van velden die bijzondere controle vereisen:
eigenaar_id— kan bepalen van wie een document of bestelling is;prijs— kan invloed hebben op het bedrag dat voor een aankoop in rekening wordt gebracht;betalingsstatus— kan aangeven of een bestelling is betaald;email_bevestigd— kan bepalen of bevestiging van het e-mailadres wordt overgeslagen.
Een klant van een webwinkel hoort bijvoorbeeld de product-ID en het gewenste aantal te versturen. De server moet de prijs vaststellen op basis van het eigen aanbod, in plaats van de waarde uit het verzoek zonder meer over te nemen.
Niet elk extra veld maakt een aanval mogelijk. Het veld moet worden geaccepteerd, toegewezen en gebruikt op een manier die invloed heeft op de werking van de applicatie. Daarom moet je bij een analyse de volledige gegevensstroom controleren, niet alleen de inhoud van het formulier.
Hoe je Mass Assignment effectief beperkt
De belangrijkste bescherming is een lijst met toegestane velden: de server accepteert voor een bepaalde bewerking uitsluitend de eigenschappen die de ontwikkelaar heeft aangewezen. Bij een gewone profielbewerking kunnen dat naam en email zijn, maar niet rol.
De aanpak kan er als volgt uitzien:
toegestane_velden = ["naam", "email"]
profielgegevens = selecteer_velden(verzoekgegevens, toegestane_velden)
werk_profiel_bij(ingelogde_gebruiker, profielgegevens)
Dit is pseudocode die het principe illustreert, geen kant-en-klare implementatie. Afhankelijk van het framework kun je de beperkingen instellen in het toewijzingsmechanisme, een validator of een afzonderlijk invoerobject, vaak een DTO genoemd. Zo’n object beschrijft welke gegevens voor een specifieke bewerking zijn toegestaan, in plaats van het volledige databaserecord weer te geven.
Alleen het formaat valideren is niet voldoende. De waarde beheerder kan een geldige rolnaam zijn, maar een gewone gebruiker mag die nog steeds niet instellen. Daarom is ook autorisatie nodig: controleren of iemand een bepaalde wijziging mag uitvoeren.
Bij een lijst met verboden velden zie je gemakkelijker iets over het hoofd: als je een nieuwe eigenschap aan het model toevoegt, moet je eraan denken die te blokkeren. Een lijst met toegestane velden maakt nieuwe eigenschappen niet automatisch beschikbaar. Controleer het precieze gedrag en de standaardbeveiliging van het gebruikte framework in de officiële documentatie.
Hoe je je eigen applicatie controleert
Test uitsluitend je eigen systeem of een omgeving waarvoor je toestemming hebt. Maak voor het bewerken van een profiel een verzoek met geldige gegevens en voeg daarna een veld toe dat de gebruiker niet mag wijzigen.
Controleer niet alleen het antwoord van de server, maar ook de opgeslagen gegevens en de daadwerkelijke rechten van het account. Een veilige implementatie moet de ongeoorloofde wijziging afwijzen of het extra veld negeren zonder de beschermde waarde te veranderen.
Bekijk om te beginnen de plekken waar alle gegevens uit een verzoek rechtstreeks worden doorgegeven aan methoden die records aanmaken of bijwerken. Leg voor elke plek de toegestane velden vast en voeg een test toe die bevestigt dat de overige velden niet gewijzigd kunnen worden.
Zie ook: Wat is Path Traversal
