SQL-injection
Hvad er SQL-injection?
At et site er sårbart for SQL-injection betyder at en angriber kan afvikle arbitrære SQL-forespørgsler gennem systemet.
Det skyldes typisk at man har et indtastningsfelt der ikke bliver valideret korrekt. F.eks. et søgefelt, som er koblet sammen med en database-søgning uden at escape brugerens indtastning.
Det helt simple eksempel – som vi utroligt ofte støder på – ser sådan ud:
<?php $res = mysql_query("SELECT * FROM books WHERE `title`='" . $_GET['search'] . "' ORDER BY id");
Her benyttes $_GET['search']
direkte i database-forespørgslen. Hvis en angriber f.eks. søger efter “';TRUNCATE books;SELECT * FROM books WHERE title='
” via søgefeltet er hele books
tabellen tømt. Det er ikke ønskværdigt 😉
Der kan udrettes endnu værre ulykker vha. SQL-injection – f.eks. kan brugernavne og kodeord afsløres, så en angriber i mange tilfælde kan overtage hjemmesiden helt!
OBS: Vi bruger et eksempel med mysql_*
-funktioner fordi det er nemt at forstå, og fordi det meget ofte er i gammel kode disse problemer eksisterer. Vi gør opmærksom på at brug af funktionerne allerede for en del år siden blev frarådet, og at de er udfaset helt i nyere versioner af php – blandt andet fordi det var så nemt at lave problemer som disse. De bør absolut ikke længere bruges. De gør din hjemmeside umulig at afvikle på php-versioner fra og med version 7. Det er med andre ord et spørgsmål om tid før dit site ikke længere blot er usikkert, men helt holder op med at fungere hvis du bruger disse!
Vi ser oftest SQL-injection sårbarheder i hjemmelavede systemer, men de er også forholdsvist almindelige i plugins af tvivlsom kvalitet til systemer som f.eks. wordpress og joomla. Der findes sågar med mellemrum denne type sårbarheder i større anerkendte systemer, men de bliver i de fleste tilfælde lukket før det får betydning.
Hvordan beskytter du dit site mod SQL-injection?
Det korte svar er ved altid at validere og / eller escape alt input fra brugeren.
Den bedste løsning er i de fleste tilfælde at lave hjemmesiden forfra i et system som f.eks. wordpress, hvor en stor gruppe af dygtige programmører altid arbejder på at finde og udbedre evt. sikkerhedsproblemer. Risikoen for at begå fejl er simpelt hen større hvis du selv konstruerer dit system.
Hvis det ikke er en mulighed, kan man naturligvis godt lappe hullerne i et usikkert system.
I ovenstående eksempel kan problemet f.eks. lappes ved at validere brugerens indtastning, og kun tillade bogstaver, tal og mellemrum:
<?php $search = $_GET['search']; if (!preg_match('#^[a-zA-Z0-9\ ]*$#', $search)) { echo 'Du kan kun bruge bogstaver og tal...'; } else { $res = mysql_query("SELECT * FROM books WHERE `title`='" . $_GET['search'] . "' ORDER BY id"); [...] }
Det er en rigtig god ide at escape brugerens input alligevel – med de gamle mysql_*
-funktioner, som er brugt i dette eksempel kan det gøres så simpelt:
<?php $res = mysql_query("SELECT * FROM books WHERE `title`='" . mysql_real_escape_string($_GET['search']) . "' ORDER BY id");
En langt mere robust løsning er at opdatere systemet til at bruge “PDO” og det der hedder “prepared statements”. Det er dog mere omfattende end vi kan beskrive her.
Vi anbefaler en google-søgning efter “SQL-injection” hvis du vil lære mere om problemet. Og for en tidssvarende løsning skal du søge efter “php pdo” eller “php prepared statements”.
Vi kan også hjælpe med at migrere dit system til wordpress eller sikre det mod sql-injection angreb. Kontakt os på 77 345 123 eller åbn en ticket for priser.