Invoervalidatie, sanitization en bescherming tegen injectieaanvallen

Lees hoe invoervalidatie en sanitization je formulieren beschermen tegen injectieaanvallen. Zo maak je formuliergegevens veilig.

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.

Veelgestelde vragen

Kan ik een WAF (Web Application Firewall) gebruiken in plaats van validatie?
Een WAF kan sommige injectieaanvallen onderscheppen voordat ze je formulier bereiken, en dat helpt. Toch vervangt het validatie en sanitization niet. Een WAF is een tweede verdedigingslinie. Je formuliercode moet zelf nog steeds gegevens valideren en opschonen. Met een WAF en invoervalidatie samen heb je meerdere beschermlagen.
Wat als een bezoeker echt speciale tekens moet invoeren?
Speciale tekens zoals apostrofs, streepjes en ampersands zijn veilig als je goed opschoont. Iemand kan bijvoorbeeld "O'Brien" of "Mary-Jane" heten. Die namen kun je veilig accepteren als je ze goed escapet voor je database (met geparametriseerde queries) en bij het weergeven (met HTML-escaping). Het gaat om goede sanitization, niet om het blokkeren van tekens.
Moet ik zowel op de client als op de server valideren?
Ja. Client-side validatie geeft bezoekers direct feedback en maakt het formulier prettiger (ze zien een typfout voordat ze versturen). Server-side validatie beschermt echt tegen aanvallen. Gebruik beide lagen. De clientkant is voor gebruiksgemak. De serverkant is voor beveiliging.
Wat is het verschil tussen escaping en sanitization?
Escaping zet gevaarlijke tekens om, zodat ze als gewone tekst worden behandeld (bijvoorbeeld < wordt <). Sanitization haalt gevaarlijke inhoud helemaal weg (bijvoorbeeld alle HTML-tags verwijderen). Escaping bewaart de gegevens, sanitization haalt de dreiging weg. Bij de meeste formuliergegevens is sanitization (tags helemaal verwijderen) veiliger dan escaping (tags omzetten).
Moet ik me zorgen maken over injectieaanvallen bij formulieren die alleen lezen?
Als een formulier alleen informatie toont (en niets verstuurt), heeft het geen injectiekwetsbaarheid. Toont dat formulier ooit wel door gebruikers ingestuurde gegevens, dan moet je nog steeds opschonen. Een aanvaller kan eerder kwaadaardige code hebben ingestuurd, en zodra je die toont, draait die code. Schoon daarom alle door gebruikers ingestuurde gegevens altijd op voordat je ze toont, ongeacht het type formulier.

Zet het meteen
in je eigen website.

Start gratis met WEMASY en bouw je site in een paar minuten.