Aanvallers vullen formulieren niet normaal in. Ze sturen code mee die is bedoeld om in je systemen te komen of gegevens te stelen. Ze kunnen JavaScript versturen dat draait in de browser van je bezoekers, SQL-commando's die je database kapotmaken, of kwaadaardige inhoud die schade veroorzaakt. Invoervalidatie en sanitization zijn de verdedigingen die deze aanvallen stoppen.
Wat je leert: wat invoervalidatie en sanitization zijn, hoe ze verschillen, hoe injectieaanvallen werken, welke bescherming past bij welk type gegevens en hoe je dit op je formulieren toepast.
Wat is invoervalidatie?
Invoervalidatie is het controleren of de gegevens die in je formulier worden ingediend het verwachte formaat hebben en aan je eisen voldoen. Het is de eerste verdedigingslinie tegen kwaadaardige invoer.
Validatie beantwoordt vragen als: is dit een e-mailadres of willekeurige tekst, is dit een getal of een woord, is dit veld leeg terwijl dat niet mag, en heeft de bezoeker iets ingevuld dat past bij dit veld of iets verdachts?
Voorbeelden van wat validatie controleert:
- Een e-mailveld moet een @-teken en een domein bevatten
- Een telefoonnummerveld mag alleen cijfers en streepjes bevatten
- Een getalveld mag geen letters bevatten
- Een verplicht veld mag niet leeg zijn
- Een wachtwoordveld moet aan een minimale lengte voldoen
Validatie gebeurt op twee plekken. Op het apparaat van de bezoeker heet dat client-side validatie. Op je server heet het server-side validatie. Client-side validatie geeft bezoekers direct feedback als ze een fout maken. Server-side validatie beschermt echt tegen aanvallen, omdat aanvallers de checks aan de clientkant kunnen omzeilen.
Wat is sanitization van invoer?
Sanitization is het verwijderen of onschadelijk maken van alles wat gevaarlijk is in gebruikersinvoer, voordat je het opslaat of verwerkt. Ook als gegevens de validatie doorstaan, kunnen ze nog code of tekens bevatten die schade moeten aanrichten.
Voorbeelden van wat sanitization doet:
- Haalt HTML-tags zoals `<script>` en `<img>` uit tekstvelden
- Haalt speciale SQL-tekens weg waarmee je database kan worden aangevallen
- Maakt speciale tekens onschadelijk (escaping), zodat ze als tekst worden behandeld en niet als code
- Beperkt de lengte van invoer om buffer overflow-aanvallen te voorkomen
Validatie en sanitization werken samen, maar hebben een ander doel. Validatie controleert of de gegevens het juiste formaat hebben. Sanitization haalt alles gevaarlijks weg, ook als het formaat technisch klopt.
Hoe injectieaanvallen werken
SQL-injectie
Een SQL-injectie gebeurt als een aanvaller SQL-code in een formulierveld zet. Als je formuliercode deze invoer niet opschoont, wordt de SQL-code uitgevoerd op je database.
Voorbeeld: een loginformulier vraagt om een e-mailadres. In plaats van zijn e-mailadres stuurt een aanvaller dit in:
' OR '1'='1 Als je formulier dit niet opschoont, kan je code een SQL-query uitvoeren die er zo uitziet:
SELECT * FROM users WHERE email = '' OR '1'='1' Het deel `OR '1'='1'` maakt de voorwaarde altijd waar, dus de query geeft alle gebruikers terug in plaats van alleen die ene met dat e-mailadres. De aanvaller is nu langs het loginsysteem gekomen.
Cross-Site Scripting (XSS)
Een XSS-aanval gebeurt als een aanvaller JavaScript-code in een formulierveld zet. Als het formulier deze code niet opschoont en opslaat, draait het JavaScript in de browser van iedereen die die gegevens later bekijkt.
Voorbeeld: een reactieformulier accepteert reacties van gebruikers. Een aanvaller stuurt dit in:
<script>alert('hacked')</script> Als dit niet wordt opgeschoond en in de database komt, draait het JavaScript zodra iemand de reacties bekijkt en verschijnt er een melding. Een gevaarlijkere versie kan cookies stelen, bezoekers doorsturen naar een phishingpagina of formuliergegevens ophalen.
Command injection
Als je formuliergegevens worden gebruikt in systeemcommando's (dat gebeurt in sommige backendsystemen), kan een aanvaller commando's van het besturingssysteem injecteren.
Voorbeeld: een formulierveld wordt gebruikt in een commando zoals:
ffmpeg -i $filename output.mp4 Als `$filename` niet wordt opgeschoond en een aanvaller `;rm -rf /` invoert, wordt het commando:
ffmpeg -i ;rm -rf / output.mp4 Het commando `rm -rf /` wordt uitgevoerd en wist bestanden van het systeem. Daarom mogen systeemcommando's nooit ongefilterde gebruikersinvoer krijgen.
Validatie en sanitization per type gegevens
E-mailadressen
Validatie: controleer of de invoer een e-mailpatroon volgt (iets als tekst@domein.extensie). Bevestig dat er alleen toegestane tekens in staan.
Sanitization: verwijder HTML-tags en speciale tekens. Bewaar alleen letters, cijfers, punten, streepjes en het @-teken.
Telefoonnummers
Validatie: controleer of er alleen cijfers, streepjes, haakjes en spaties in staan. Check of de lengte klopt voor het verwachte land.
Sanitization: verwijder alle niet-numerieke tekens, behalve streepjes en haakjes. Haal waar nodig voorloopnullen of spaties weg.
Tekstvelden (reacties, namen, adressen)
Validatie: controleer of het veld niet leeg is en of de lengte redelijk is (geen miljoenen tekens).
Sanitization: verwijder of escape HTML-tags, JavaScript en speciale SQL-tekens. Bewaar alleen gewone tekst en eenvoudige leestekens.
Getallen en bedragen
Validatie: controleer of de invoer een getal is. Controleer bij prijzen of aantallen of het een positief getal is.
Sanitization: verwijder alle niet-numerieke tekens. Rond zo nodig af op het juiste aantal decimalen.
Wachtwoorden
Validatie: controleer de minimale lengte (minstens 8 tekens) en eis eventueel een mix van hoofdletters, kleine letters, cijfers en symbolen.
Sanitization: pas wachtwoorden niet aan en haal er niets uit. Ze moeten in hun exacte vorm worden bewaard (als hash, nooit als leesbare tekst). Als je tekens uit een wachtwoord haalt, kunnen gebruikers niet meer inloggen.
Bestandsuploads
Validatie: controleer of het bestandstype klopt met wat je verwacht (bijvoorbeeld alleen pdf-bestanden, alleen afbeeldingen). Controleer dat het bestand niet te groot is.
Sanitization: hernoem het bestand zodat aanvallers geen speciale bestandsnamen kunnen gebruiken. Scan het bestand op malware. Sla het op buiten de webroot, zodat het niet als code kan worden uitgevoerd.
Hoe je validatie en sanitization toepast
Client-side (in de browser)
Gebruik HTML5-validatieattributen om bezoekers direct feedback te geven:
<input type="email" name="email" required> <input type="tel" name="phone" pattern="[0-9]{10}"> <input type="number" name="age" min="0" max="120"> Dit vangt duidelijke fouten op en maakt het formulier prettiger in gebruik. Client-side validatie is wel te omzeilen, dus het is op zichzelf geen beveiliging.
Server-side (op je server)
Hier gebeurt de beveiliging. Je backendcode moet elk stukje data valideren en opschonen:
// Pseudo-code example if (email does not match email pattern) { reject the submission } // Remove HTML tags sanitized_comment = remove_html_tags(comment_text) // Escape special characters for database safe_name = escape_sql_characters(user_name) // Only then store the data store_in_database(safe_name, sanitized_comment) Gebruik geparametriseerde queries voor databases
De beste verdediging tegen SQL-injectie zijn geparametriseerde queries (ook wel prepared statements genoemd). In plaats van gebruikersinvoer direct in een SQL-query te zetten, gebruik je plaatshouders en geef je de data apart mee:
// Bad (vulnerable): query = "SELECT * FROM users WHERE email = '" + email + "'" // Good (safe): query = "SELECT * FROM users WHERE email = ?" execute(query, [email]) Bij geparametriseerde queries weet de SQL-parser dat de gebruikersinvoer data is en geen code. Ook als een aanvaller SQL-code invoert, wordt die als gewone tekst behandeld.
Gebruik bibliotheken en frameworks
Schrijf sanitization-code niet zelf vanaf nul. Gebruik bewezen bibliotheken die hiervoor zijn gemaakt. In PHP gebruik je htmlspecialchars() of een bibliotheek zoals HTML Purifier. In Python gebruik je de module `html` of een bibliotheek zoals bleach. In Node.js gebruik je `express-validator` of iets vergelijkbaars. Deze bibliotheken zijn getest en worden bijgewerkt voor nieuwe soorten aanvallen.
Veelgemaakte fouten bij validatie en sanitization
Alleen valideren aan de clientkant. Client-side validatie is voor gebruiksgemak, niet voor beveiliging. Een aanvaller kan het omzeilen. Je moet ook op de server valideren.
Gevaarlijke tekens blokkeren in plaats van veilige tekens toestaan. Als je SQL-injectie probeert te stoppen door puntkomma's en aanhalingstekens te verwijderen, vinden aanvallers er een weg omheen. Sta liever alleen de tekens toe die je verwacht (bij telefoonnummers alleen cijfers en streepjes) en weiger de rest.
Vertrouwen op het gegevenstype van het formulierveld. Bij een getalveld stuurt de browser tekst die op een getal lijkt. Je server moet nog steeds controleren of het echt een getal is voordat je het gebruikt. Ga er nooit van uit dat het gegevenstype klopt.
Vergeten om weergegeven data op te schonen. Ook als gegevens veilig zijn opgeslagen, kunnen aanvallers code injecteren die draait in de browser van bezoekers, als je die gegevens op een webpagina toont zonder de HTML te escapen.
Opschonen in de verkeerde volgorde. Valideer eerst (is dit het juiste formaat?) en schoon daarna op (is dit veilig?). Als je eerst opschoont en dan valideert, wijs je misschien gegevens af die eigenlijk veilig waren.
Wat WEMASY doet voor invoervalidatie
WEMASY valideert formuliervelden automatisch op basis van het veldtype dat je kiest. E-mailvelden worden gecontroleerd op een geldig e-mailformaat. Getalvelden worden gecontroleerd op numerieke invoer. Verplichte velden worden gecontroleerd op inhoud voordat het formulier wordt verstuurd. Aan de serverkant schoont WEMASY alle invoer op en haalt HTML, JavaScript en andere gevaarlijke code weg voordat inzendingen worden opgeslagen. Jij kiest welke velden je verzamelt, WEMASY regelt de validatie en sanitization op de achtergrond.
Bekijk op de prijspagina welke formulierfuncties in jouw abonnement zitten.