När angripare riktar in sig på formulär fyller de inte i dem som vanligt. De skickar i stället kod som är gjord för att ta sig in i dina system eller stjäla data. De kan skicka JavaScript som körs i besökarnas webbläsare, SQL-kommandon som förstör din databas eller skadligt innehåll. Indatavalidering och sanering är försvaret som stoppar de här attackerna.
Det här lär du dig: Vad indatavalidering och sanering är, hur de skiljer sig åt, hur injektionsattacker fungerar, vilka skydd som fungerar för olika typer av data och hur du inför dem i dina formulär.
Vad är indatavalidering?
Indatavalidering betyder att du kontrollerar att data som skickas in i formuläret har det format du förväntar dig och uppfyller dina krav. Det är den första försvarslinjen mot skadlig indata.
Validering svarar på frågor som om det här är en e-postadress eller slumpmässig text, om det är ett tal eller ett ord, om fältet är tomt när det inte ska vara det och om besökaren skrev något som är rimligt för fältet eller något misstänkt.
Exempel på vad validering kontrollerar:
- Ett e-postfält ska innehålla ett @-tecken och en domän
- Ett telefonnummerfält ska bara innehålla siffror och bindestreck
- Ett nummerfält ska inte innehålla bokstäver
- Ett obligatoriskt fält ska inte vara tomt
- Ett lösenordsfält ska uppfylla kraven på minsta längd
Validering sker på två ställen. På besökarens enhet kallas den validering på klientsidan. På din server kallas den validering på serversidan. Validering på klientsidan ger besökaren direkt återkoppling vid ett misstag. Validering på serversidan är det som faktiskt skyddar mot attacker, eftersom angripare kan gå förbi kontroller på klientsidan.
Vad är sanering av indata?
Sanering betyder att du tar bort eller oskadliggör allt farligt i användarens indata innan du lagrar eller behandlar den. Även om data klarar valideringen kan den fortfarande innehålla kod eller tecken som är gjorda för att skada.
Exempel på vad sanering gör:
- Tar bort HTML-taggar som `<script>` och `<img>` från textfält
- Tar bort SQL-specialtecken som kan användas för att ta sig in i databaser
- Maskerar specialtecken så att de behandlas som text och inte som kod
- Begränsar indatans längd för att förhindra buffertöverflödesattacker
Validering och sanering fungerar tillsammans men har olika syften. Validering kontrollerar att data har rätt format. Sanering tar bort allt farligt även när formatet tekniskt sett är korrekt.
Så fungerar injektionsattacker
SQL-injektion
En SQL-injektion sker när en angripare skriver in SQL-kod i ett formulärfält. Om formulärets kod inte sanerar indatan körs SQL-koden i din databas.
Exempel: Ett inloggningsformulär ber om en e-postadress. I stället för sin e-postadress skickar angriparen in:
' OR '1'='1 Om formuläret inte sanerar detta kan din kod köra en SQL-fråga som ser ut så här:
SELECT * FROM users WHERE email = '' OR '1'='1' Delen `OR '1'='1'` gör villkoret alltid sant, så frågan returnerar alla användare i stället för bara den med den e-postadressen. Angriparen har nu gått förbi inloggningen.
Cross-Site Scripting (XSS)
En XSS-attack sker när en angripare skickar in JavaScript-kod i ett formulärfält. Om formuläret inte sanerar koden och sparar den, körs JavaScript i webbläsaren hos alla som senare tittar på den datan.
Exempel: Ett kommentarsformulär tar emot användarkommentarer. En angripare skickar in:
<script>alert('hacked')</script> Om detta inte sanerats och sparas i databasen körs JavaScript och visar en varning när någon tittar på kommentarsfältet. En farligare version kan stjäla cookies, skicka besökare till en nätfiskesida eller hämta ut formulärdata.
Kommandoinjektion
Om dina formulärdata används i systemkommandon (vilket förekommer i vissa backend-system) kan en angripare injicera kommandon till operativsystemet.
Exempel: Ett formulärfält används i ett kommando som:
ffmpeg -i $filename output.mp4 Om `$filename` inte sanerats och en angripare skickar in `;rm -rf /` blir kommandot:
ffmpeg -i ;rm -rf / output.mp4 Kommandot `rm -rf /` körs och raderar filer från systemet. Därför ska systemkommandon aldrig få osanerad indata från användare.
Validering och sanering för olika datatyper
E-postadresser
Validering: Kontrollera att indatan matchar ett e-postmönster (något i stil med text@domän.ändelse). Bekräfta att den bara innehåller tillåtna tecken.
Sanering: Ta bort alla HTML-taggar och specialtecken. Behåll bara bokstäver, siffror, punkter, bindestreck och @-tecknet.
Telefonnummer
Validering: Kontrollera att det bara innehåller siffror, bindestreck, parenteser och mellanslag. Kontrollera att längden stämmer för det land du förväntar dig.
Sanering: Ta bort alla icke-numeriska tecken utom bindestreck och parenteser. Ta bort inledande nollor eller mellanslag vid behov.
Textfält (kommentarer, namn, adresser)
Validering: Kontrollera att fältet inte är tomt och att längden är rimlig (inte miljontals tecken).
Sanering: Ta bort eller maskera HTML-taggar, JavaScript och SQL-specialtecken. Behåll bara ren text och enkel interpunktion.
Tal och belopp
Validering: Kontrollera att indatan är ett tal. För priser eller antal ska du kontrollera att det är ett positivt tal.
Sanering: Ta bort alla icke-numeriska tecken. Avrunda till rätt antal decimaler vid behov.
Lösenord
Validering: Kontrollera minsta längd (minst 8 tecken) och kräv gärna en blandning av versaler, gemener, siffror och symboler.
Sanering: Ta inte bort tecken i lösenord och ändra dem inte. De ska lagras exakt som de är (hashade, aldrig i klartext). Om du tar bort tecken från ett lösenord kan användarna inte logga in.
Filuppladdningar
Validering: Kontrollera att filtypen är den du förväntar dig (till exempel bara PDF-filer eller bara bilder). Kontrollera att filen inte är för stor.
Sanering: Byt namn på filen så att angripare inte kan använda särskilda filnamn. Skanna filen efter skadlig kod. Lagra den utanför webbrotkatalogen så att den inte kan köras som kod.
Så inför du validering och sanering
På klientsidan (i webbläsaren)
Använd HTML5-attribut för validering av indata för att ge besökarna direkt återkoppling:
<input type="email" name="email" required> <input type="tel" name="phone" pattern="[0-9]{10}"> <input type="number" name="age" min="0" max="120"> Det fångar uppenbara misstag och förbättrar upplevelsen. Validering på klientsidan kan dock gå att kringgå, så den är inget säkerhetsskydd i sig.
På serversidan (på din server)
Det är här säkerheten sker. Din backend-kod måste validera och sanera varje uppgift:
// 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) Använd parametriserade frågor mot databaser
Det bästa försvaret mot SQL-injektion är parametriserade frågor (kallas också förberedda satser). I stället för att lägga användarens indata direkt i en SQL-fråga använder du platshållare och skickar datan separat:
// Bad (vulnerable): query = "SELECT * FROM users WHERE email = '" + email + "'" // Good (safe): query = "SELECT * FROM users WHERE email = ?" execute(query, [email]) Med parametriserade frågor vet SQL-tolken att användarens indata är data och inte kod. Även om en angripare skickar in SQL-kod behandlas den som vanlig text.
Använd bibliotek och ramverk
Skriv inte saneringskod från grunden. Använd etablerade bibliotek som är gjorda för detta. I PHP kan du använda htmlspecialchars() eller ett bibliotek som HTML Purifier. I Python kan du använda modulen `html` eller ett bibliotek som bleach. I Node.js kan du använda `express-validator` eller liknande. Biblioteken är testade och uppdateras för att klara nya typer av attacker.
Vanliga misstag vid validering och sanering
Att bara validera på klientsidan. Validering på klientsidan är till för användarupplevelsen, inte för säkerheten. En angripare kan gå förbi den. Du måste validera på servern också.
Att svartlista farliga tecken i stället för att vitlista säkra. Om du försöker stoppa SQL-injektion genom att ta bort semikolon och citattecken hittar angripare vägar runt det. Vitlista i stället de tecken du förväntar dig (för telefonnummer bara siffror och bindestreck) och avvisa allt annat.
Att lita på formulärfältets datatyp. Har du ett nummerfält skickar webbläsaren text som ser ut som ett tal. Din server måste ändå kontrollera att det verkligen är ett tal innan du använder det. Anta aldrig att datatypen stämmer.
Att glömma sanera data som visas. Även om data lagras säkert kan angripare injicera kod som körs i besökarnas webbläsare när de tittar på datan, om du visar den på en webbsida utan att maskera HTML.
Att sanera i fel ordning. Validera först (är det här rätt format?) och sanera sedan (är det här säkert?). Om du sanerar först och validerar sedan kan du avvisa data som faktiskt var säker.
Det här gör WEMASY för indatavalidering
WEMASY validerar formulärfält automatiskt utifrån den fälttyp du väljer. E-postfält kontrolleras för giltigt e-postformat. Nummerfält kontrolleras för numerisk indata. Obligatoriska fält kontrolleras så att de har innehåll innan formuläret skickas. På serversidan sanerar WEMASY all indata och tar bort HTML, JavaScript och annan farlig kod innan inskick sparas. Du väljer vilka fält som ska samlas in, och WEMASY sköter validering och sanering i bakgrunden.
Se vilka formulärfunktioner som ingår i din plan på prissidan.