nemlig
(5.151 point. Point ude: 0)
Sikkerhed mod SQl-injektion
Hej.
Jeg har en kontaktform med nogle input-felter, som er defineret jf. nedenfor:
Men sikkerheden er vist nok hullet som en si.
Kan I bidrage lidt med, hvad der kan gøres.
<input type="text" name="adresse1" size="40">
Jeg smider dem i MySQL sådan her:
$sql = "INSERT INTO tabelnavn SET adresse1='".$_POST['adresse1']."'";
database($sql);
Og database funktionen ser sådan her ud:
function database($sql){//Funktion der laver alm databasekald og returnerer resultatet
$config = ini();//Hent databaseparametre
$conn = mysql_connect($config[db_serv],$config[db_user],$config[db_pass]);//Åben databaseforbindelse
if (!$conn) {
die('Could not connect: ' . mysql_error());
}
$res = mysql_db_query($config[db_base],$sql); //Udfør forespørgsel
mysql_close($conn);//Luk databaseforbindelse
if (!$res) {//Tjek om det gik godt
die("<b>Databasefejl:<br></b>" . mysql_error($conn) ."<b><br>MySQL-sætningen var:<br></b>". $sql);//Udskriv fejlmelding og stop udførsel
}
return $res;//Returner resultat af forespørgsel
}
Skrevet ons. d. 12. december 2007 kl. 21:53:33| #1
Skrevet ons. d. 12. december 2007 kl. 22:06:32| #2
Tag også et kig i PHP dokumentionen:
http://dk2.php.net/ (...)
Skrevet ons. d. 12. december 2007 kl. 22:13:13| #3
Jeps - jeg er i gang med at kigge begge steder.
Men jeg kan ikke helt gennemskue, hvordan jeg i ovenstående eksempel kan anvende "mysql_real_escape_string". Jeg leger lidt med det, men har I et nemt forslag, vil jeg da gerne se det.
Skrevet ons. d. 12. december 2007 kl. 22:18:10| #4
Det skal gøres på data *før* at de kommer i SQL strengen:
$adresse1 = mysql_real_escape_string($_POST['adresse1']);
$sql = "INSERT INTO tabelnavn SET adresse1='$adresse1'";
database($sql);
Skrevet ons. d. 12. december 2007 kl. 22:21:46| #5
Ok tusind tak I 2. Sender I lige et svar.
Skrevet ons. d. 12. december 2007 kl. 22:28:08| #6
Hvis nyere PHP saa var mysqli og prepared statement et godt alternativ.
Skrevet ons. d. 12. december 2007 kl. 22:36:32| #7
Hov - jeg får følgende fejl pr. inputfelt:
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'ODBC'@'localhost' (using password: NO) in C:\wamp\www\hummelmosen\kontaktform.php on line 31
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in C:\wamp\www\hummelmosen\kontaktform.php on line 31
Skrevet ons. d. 12. december 2007 kl. 22:59:17| #8
din database-funktion er ikke så smart, da den opretter en connection for hver query... Connect til databasen én gang, og brug så den connection til samtlige queries... Syntaksen for mysql_real_escape_string er mysql_real_escape_string(unescaped_string, database_connection) - Du kan dog nok bruge mysql_escape_string i stedet (uden connection).
Skrevet ons. d. 12. december 2007 kl. 23:06:48| #9
Skrevet tor. d. 13. december 2007 kl. 11:03:54| #10
Du skal *ikke* bruge den alm. escape_string, kun real_escape_string (og da PHP husker den seneste connection kan du faktisk udelade connectionen, såfremt den er åben - hvilket den bør være). Hvis du bruger mysql_escape_string risikerer du problemer hvis forbindelsen bruger et multi-byte tegnsæt, da den opererer på byte-niveau, og ikke tegn-niveau.
Helt optimalt er at benytte mysqli og parameters (der har før været fejl i databasernes escaping-kode), men det er ikke altid en mulighed.
Skrevet tor. d. 13. december 2007 kl. 12:37:51| #11
Yep, hvis du bruger andet end ISO-8859-1/Latin-1 som tegnsæt, må du ikke bruge mysql_escape_string - Hvis du gør, er den ok - Men hellere bare væn dig til at bruge mysql_real_escape_string :)
Jeg ville dele din database-funktion op i to, en der connecter og en der fyrer queries af - Eller endnu bedre - Brug en databasewrapper som f.eks. PEAR::MDB2 -
http://pear.php.net/ (...)Eller som pidgeot skriver, brug mysqli og prepared statements!
Skrevet tor. d. 13. december 2007 kl. 18:27:32| #12
Springer over på denne her. :^)
Skrevet tor. d. 13. december 2007 kl. 19:12:10| #13
Hold da op, hvor er jeg en klovn. I min funktionsliste ligger der i forvejen en funktion, som sikrer mod SQl-injektion. Den ser sådan her ud:
function mysqlRealEscapeString($input)
{
$output = ''; //Bruges til output senere.
$config = ini();//Hent databaseparametre
$conn = mysql_connect($config[db_serv],$config[db_user],$config[db_pass]);//Åben databaseforbindelse
$output = mysql_real_escape_string($input);
mysql_close($conn);//Luk databaseforbindelse
return $output;
}
Og jeg anvender så funktionen på denne måde:
$adresse1 = MysqlRealEscapeString($_POST['adresse1']);
Og det virker. Jeg forstår ikke, hvorfor den virker jf. kommentarerne ovenfor om gentagne connects.
Skrevet tor. d. 13. december 2007 kl. 19:44:10| #14
Den fungerer, fordi der er en forbindelse den kan tage et tegnsæt fra - men det er enormt ineffektiv kode at åbne og lukke forbindelsen konstant.
Skrevet tor. d. 13. december 2007 kl. 19:59:29| #15
Jeg forstår ikke, hvorfor den åbner og lukker hele tiden. Funktionen SQL bliver da kun kaldt 1 gang??
Skal jeg opsplitte funtionen i 2, således jeg connecter med:
$config = ini();//Hent databaseparametre
$conn = mysql_connect($config[db_serv],$config[db_user],$config[db_pass]);//Åben databaseforbindelse
if (!$conn) {
die('Could not connect: ' . mysql_error());
}
Derefter:
$res = mysql_db_query($config[db_base],$sql); //Udfør forespørgsel
mysql_close($conn);//Luk databaseforbindelse
if (!$res) {//Tjek om det gik godt
die("<b>Databasefejl:<br></b>" . mysql_error($conn) ."<b><br>MySQL-sætningen var:<br></b>". $sql);//Udskriv fejlmelding og stop udførsel
}
return $res;//Returner resultat af forespørgsel
}
Skrevet tor. d. 13. december 2007 kl. 21:26:43| #16
hvorfor vil man bruge databasen til at undgå sql-injection, det kan php da selv klare, så er man også fri for at kalde fra webserver til database server hver gang.......
Skrevet fre. d. 14. december 2007 kl. 12:55:43| #17
Yep, nemlig, split den op i to så du kun connecter én gang :)
Skrevet fre. d. 14. december 2007 kl. 13:04:41| #18
Mungojerrie, hvis du tænker på addslashes/magic quotes, så tager du komplet fejl. Den kan ikke bruges, da der er andre tegn der kan bruges end dem den håndterer (for ikke at tale om alle de problemer du kan få hvis du bruger et multi-byte tegnsæt til kommunikation med databasen).
Det er ikke uden grund at den anbefalede måde at skrive sikker kode på er at fjerne magic quotes og håndtere det med parameters (eller databasens escaping-funktion, om nødvendigt) - det holder ikke at bruge addslashes eller på anden måde skrive sin egen escaping, fordi du ikke har begreb om hvad der kan forårsage problemer, og næppe får skrevet kode der håndterer forskellige tegnsæt korrekt.
Derudover forsvinder magic quotes langt om længe i PHP6 - så det er heller ikke en løsning der er holdbar i længden.
Skrevet tor. d. 20. december 2007 kl. 14:31:48| #19
Jeg takker for alle input. Meld jer lige på banen I andre, så jeg kan tildele point.
Skrevet tor. d. 20. december 2007 kl. 14:45:49| #20
Jeg ved ikke om det inkluderer mig, men ellers står det dig frit for at afvise mit svar :)
Skrevet tor. d. 20. december 2007 kl. 17:34:06| #21