Vinnaren i pepparkakshustävlingen!
2011-11-20, 14:13
  #1
Moderator
Protons avatar
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:

Kod:
<?php
$result 
mysql_query("SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'");
och sedan kommer frågan oftast "Varför funkar den inte"?

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:
$result mysql_query("SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'") or die(mysql_error()); 
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.

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:
<?php
$sql 
"SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'";
$result mysql_query($sql)or die(mysql_error());
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:

Kod:
$sql "SELECT * FROM sometable WHERE keyword like '%".$_GET['search']."'";
echo 
$sql;
$result mysql_query($sql)or die(mysql_error()); 
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.

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!!
2012-08-19, 21:58
  #2
Moderator
Protons avatar
För den som är vetgirig angående PDO och hur man använder det har medlemmen ath0 satt ihop en liten guide som hittas på https://www.flashback.org/t1937379

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback