25 besökare, 8 medlemmar och 4 Studenter är online nu
Loopia

PHP och MySQL

När du använder PHP finns alltid en risk att dina script blir manipulerade. Målsättningen med den här guiden är att göra dig medveten om problemen och ge tips om var du kan hitta mer information. Vi visar även hur du kan skydda dig mot vanliga SQL injections i MySQL.

 

Vad är SQL injections?

SQL injections innebär att din MySQL-databas manipuleras genom att indata i MySQL-frågan ändras. Detta kan ske med flera olika metoder beroende på hur din kod är skriven. Ett vanligt fel är att inte använda någon form av indatakontroll av vad som skickas eller hämtas från MySQL-tabellerna. Genom att lägga till kod i frågesträngarna kan databasen manipuleras att visa skyddad information eller lägga till data i tabellerna. En en allvarligare typ av SQL injections är att kolumner eller hela tabellen raderas.

 

Exempel på SQL injection

Exemplet nedan visar hur en vanlig inloggning kan utnyttjas till en SQL injection. Formuläret nedan visar hur inloggningen sker med användarnamnet "lisa" och lösenordet "lisa1234" vilket är de riktiga användaruppgifter som finns i MySQL-tabellen:

Kodavsnittet som bearbetar informationen från formulärets POST-data lagrar dem i variablerna $anvandarID och $password:

<?php

$anvandarID = $_POST["anvandarID"];
$password = $_POST["
losenord"];

$query = "SELECT username FROM usertable WHERE username = '$anvandarID' AND password = '$password'";

?>

Informationen som skickas till MySQL-databasen ser ut så här:

SELECT username FROM usertable WHERE username = 'lisa' AND password = 'lisa1234'

MySQL-frågan i exemplet är öppen för att lägga till mer kod i frågesträngen.

En vanlig SQL injection är att lägga till villkoret OR där två värden jämförs med varandra. Här är några exempel:

' OR '1'='1
' OR ''='
' OR 'hacked'='hacked

Principen är att värdet i raden är tomt eller att siffran "1" är lika med "1" vilket ju alltid stämmer. Villkoret för WHERE i frågesträngen är alltså uppfyllt.

Vi behöver inte veta namnet på MySQL-tabellen eller någon av kolumnerna för att utföra den här typen av SQL injection. Vi använder formuläret för att lägga till villkoret OR både som användarnamn och lösenord i inloggningen:

Informationen som skickas till MySQL-databasen ser ut så här:

SELECT username FROM usertable WHERE username = '' OR '1'='1' AND password = '' OR '1'='1'

Vi loggar in utan problem och har tillgång till de skyddade sidorna!

Om användaruppgifter som ger behörighet på administratörs-nivå finns i tabellen kan vi nu gå vidare och utföra andra mer eller mindre skadliga åtgärder.

SQL injectionen som används ovan fungerar bara mot MySQL-databaser men samma injection kan göras mot en SQL-databas med liknande frågesträngar.

 

 

Förhindra MySQL injections

Det finns flera åtgärder för att skriva säkrare kod och förhindra de vanligaste typerna av SQL injections.

En metod är att använda funktionen preg_match (regular expressions, reguljära uttryck) för att kontrollera indata i frågesträngarna.

Läs mer om preg_match i guiden Formmail - skicka formulär till epost »

En annan metod är att använda hashing i frågesträngarna och den metoden är vanlig vid inloggning där den skickade informationen inte behöver kunna reverseras.

En av de åtgärder som är mest effektiv är att använda funktionen addslashes som lägger till escape-tecknet backslash \ för att att inaktivera enkla citationstecken ( ' ) och dubbla citationstecken ( " ) innan frågan skickas till MySQL-databasen.

Läs mer om "addslashes" hos PHP.net

OBS! Om du använder senare versioner än PHP 4.3.0 ska du (istället för addslashes) använda funktionen mysql_real_escape_string för escape av specialtecknen i strängarna innan de skickas till MySQL-databasen.

mysql_real_escape_string

En förutsättning för att använda mysql_real_escape_string är att du är redan är ansluten till databasen med mysql_connect (läs mer i guiden PHP och MySQl » )

OBS! Det här är den metod som rekommenderas. Använd alltid mysql_real_escape_string i frågesträngar mot MySQL så har du ett bra skydd mot SQL injections!

Här är samma kodavsnitt som tidigare, men nu används mysql_real_escape_string i variablerna:

<?php

$anvandarID = mysql_real_escape_string($_POST["anvandarID"]);
$password = mysql_real_escape_string($_POST["losenord"]);

$query = "SELECT username FROM usertable WHERE username = '$anvandarID' AND password = '$password'";

?>

Om injektion enligt ovan utförs så ser informationen som skickas till MySQL-databasen ser ut så här:

SELECT username FROM usertable WHERE username =
'\' OR \'1\'=\'1' AND password = '\' OR \'1\'=\'1'

Alla citationstecken är escapade och inloggningen misslyckas.

Slutsats: Kör alltid indata genom funktionen mysql_real_escape_string innan de används i MySQL-frågan!

 

 

Mer information om PHP säkerhet och SQL injections

Exemplet i den här guiden visar hur du kan skydda dig mot SQL-injections vid en inloggning där PHP och MySQL används. Det finns andra typer av intrång och säkerhetsrisker beroende på vilken databas och scriptspråk du använder.

Här är länkar till resurser där du kan läsa mer om säkerhet men även till tips om hur du kan utföra olika typer av "hack". Genom att du får kunskap om hur intrång kan genomföras så lär du dig också vilka risker som finns och hur du kan skydda din webbplats och databaser.

PHP.net - mysqli-real-escape-string 

PHP.net - SQL Injection 

PHP Security Consortium - PHP Security guide 

SQL Injection Cheat Sheet - lathund för injections 

https://www.guru99.com/learn-sql-injection-with-practical-example.html