2011-11-20, 14:13
#1
Då och då förekommer det frågor i PHP-forumet om SQLer och varför dessa inte funkar alls, eller som ger fel svar tillbaka som man inte alls hade tänkt sej. Det vanliga scenariot vi stöter på här är kod som påminner om denna:
Bortsett från det enorma säkerhetshålet man öppnat här genom att skicka in helt ovaliderad och okontrollerad data direkt från anropet till sitt script finns det inte mycket att gå på. Vi har till exempel ingen aning om scriptet pajjar, om frågan körs, eller om vi får ett resultat alls. Dessutom vet vi inte ens vad för fråga vi försöker köra.
Ett väldigt enkelt sätt att ta reda på till att börja med, om sqlen är korrekt ur en syntaxmässig synvinkel är att lägga till or die efter frågan, samt ta reda på varför frågan pajjade:
En enkel lösning på det problemet är att sätta upp sin fråga i en separat variabel eftersom man då kan skriva ut innehållet i denna vid behov:
Det säkerhetsproblem med denna SQL jag talat om är känt som SQL injection:
http://en.wikipedia.org/wiki/SQL_injection
Denna bug har sänkt åtskilliga webplatser och databasservrar, antingen beroende på okunskap om buggen, eller på rent slarv.
Oavsett vilket är det väldigt enkelt att komma undan den om man har i åtanke att VARJE form av data som kommer från användaren (dvs formulärdata, cookies, GET-data i urler, sessionsdata, uppladdade filer etc) är att betrakta som icke-säker och icke-giltig till motsatsen bevisats och är fulltsändigt livsfarlig att använda innan man försäkrat sej om datats giltighet.
Vad beträffar sql-injektionen är ett sätt att göra det svårare för en angripare att använda de inbygga konstruktioner som finns för detta i php, mysql_real_escape_string() är väl en av de mer kända vid det här laget, prepared statements är en annan.
Håller man detta i åtanke när man kodar kommer man undan många källor till frustration, man gör det dessutm väldigt mycket svårare för en hacker att angripa den webapplikation an knåpat ihop under många timmars slit.
Happy coding!!
Kod:
och sedan kommer frågan oftast "Varför funkar den inte"?
<?php
$result = mysql_query("SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'");
Bortsett från det enorma säkerhetshålet man öppnat här genom att skicka in helt ovaliderad och okontrollerad data direkt från anropet till sitt script finns det inte mycket att gå på. Vi har till exempel ingen aning om scriptet pajjar, om frågan körs, eller om vi får ett resultat alls. Dessutom vet vi inte ens vad för fråga vi försöker köra.
Ett väldigt enkelt sätt att ta reda på till att börja med, om sqlen är korrekt ur en syntaxmässig synvinkel är att lägga till or die efter frågan, samt ta reda på varför frågan pajjade:
Kod:
Pajjar frågan där kommer vi få ut ett felmeddelande som mysql ger ifrån sej vid en inkorrekt ställd fråga. Det intressanta kvarstår dock, nämligen hur vi tar reda på vad det var för något vi försökte göra egentligen. Vi har fortfarande ingen aning om vad vi försökte köra för fråga.
$result = mysql_query("SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'") or die(mysql_error());
En enkel lösning på det problemet är att sätta upp sin fråga i en separat variabel eftersom man då kan skriva ut innehållet i denna vid behov:
Kod:
Pajjar frågan nu har vi iaf en chans att få reda på varför, det enda vi bgehöver göra är att lägga till en utskrift:
<?php
$sql = "SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'";
$result = mysql_query($sql)or die(mysql_error());
Kod:
nu kommer frågan skrivas ut och nu kan vi dessutom köra den direkt mot databasen för att se vad den gör. I detta läge blir det dessutom väldigt enkelt att upptäcka saknade tecken här och där, eller andra dumheter man kan ha försökt göra.
$sql = "SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'";
echo $sql;
$result = mysql_query($sql)or die(mysql_error());
Det säkerhetsproblem med denna SQL jag talat om är känt som SQL injection:
http://en.wikipedia.org/wiki/SQL_injection
Denna bug har sänkt åtskilliga webplatser och databasservrar, antingen beroende på okunskap om buggen, eller på rent slarv.
Oavsett vilket är det väldigt enkelt att komma undan den om man har i åtanke att VARJE form av data som kommer från användaren (dvs formulärdata, cookies, GET-data i urler, sessionsdata, uppladdade filer etc) är att betrakta som icke-säker och icke-giltig till motsatsen bevisats och är fulltsändigt livsfarlig att använda innan man försäkrat sej om datats giltighet.
Vad beträffar sql-injektionen är ett sätt att göra det svårare för en angripare att använda de inbygga konstruktioner som finns för detta i php, mysql_real_escape_string() är väl en av de mer kända vid det här laget, prepared statements är en annan.
Håller man detta i åtanke när man kodar kommer man undan många källor till frustration, man gör det dessutm väldigt mycket svårare för en hacker att angripa den webapplikation an knåpat ihop under många timmars slit.
Happy coding!!