Oprettet ons. d. 12. december 2007 kl. 21:48:45

nemlig
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

nielle
nielle (159.526 point)
Tag også et kig i PHP dokumentionen:

http://dk2.php.net/ (...)

Skrevet ons. d. 12. december 2007 kl. 22:13:13| #3

nemlig
nemlig (5.151 point)
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

nielle
nielle (159.526 point)
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

nemlig
nemlig (5.151 point)
Ok tusind tak I 2. Sender I lige et svar.

Skrevet ons. d. 12. december 2007 kl. 22:28:08| #6

arne_v
arne_v (1.016.169 point)
Hvis nyere PHP saa var mysqli og prepared statement et godt alternativ.

Skrevet ons. d. 12. december 2007 kl. 22:36:32| #7

nemlig
nemlig (5.151 point)
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

coderdk
coderdk (160.399 point)
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

pidgeot
pidgeot (51.189 point)
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

coderdk
coderdk (160.399 point)
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

nielle
nielle (159.526 point)
Springer over på denne her. :^)

Skrevet tor. d. 13. december 2007 kl. 19:12:10| #13

nemlig
nemlig (5.151 point)
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

pidgeot
pidgeot (51.189 point)
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

nemlig
nemlig (5.151 point)
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

mungojerrie
mungojerrie (15.745 point)
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

coderdk
coderdk (160.399 point)
Yep, nemlig, split den op i to så du kun connecter én gang :)

Skrevet fre. d. 14. december 2007 kl. 13:04:41| #18

pidgeot
pidgeot (51.189 point)
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

nemlig
nemlig (5.151 point)
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

pidgeot
pidgeot (51.189 point)
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

coderdk
coderdk (160.399 point)
Ingen til mig :)

Skriv et indlæg




Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] [img]link til billede[/img]
Web- og emailadresser omdannes automatisk til links

Log ind

   

   

Seneste spørgsmål

Brugerliste med link til profil

Oprettet den 26. maj 2012 kl. 14.29
sayn giver 30 point for svar | Giv et svar »

php curl driller

Oprettet den 26. maj 2012 kl. 08.31
PHPnQrd giver 200 point for svar | Giv et svar »

Array i array

Oprettet den 25. maj 2012 kl. 08.32
sebster giver 60 point for svar | Giv et svar »



   




Tips & Tricks fra PC World

Teaser billede

Læserne: Her er vores værste it-indkøb

Det er ikke al it-udstyr, som er det rene guld. Her er nogle af læsernes skrækhistorier.


Anmeldelser fra PC World

Teaser billede

Test: Mobil med Ferrari-design - og en Trabant-motor

Motorola har begået endnu en smartphone med lækkert design og potentiale til at være blandt de bedste. Men den når ikke i mål. Se her hvorfor.


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Sådan siger du farvel til Facebook

Læs her, hvordan du dropper Facebook og i stedet anvender nogle brugervenlige alternativer, så du stadig kan være social på nettet.


Nyheder fra Computerworld

Teaser billede

Galleri: De fedeste håndholdte gennem 40 år

Her har du de mest banebrydende håndholdte computere gennem alle tider.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger