WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   [PHP] Bästa sätt att undvika SQL injections? (https://www.wn.se/forum/showthread.php?t=27368)

Jine 2008-02-21 17:51

Hej!

Jag har en liten kort fråga.

Jag har läst rätt mycket om tekniker att STOPPA SQL injections, och har kommit på ett "bra" sätt att stoppa det, TROR jag?
Sättet är lätt att infoga i redan existerande kod och är rätt simpelt.
Frågan är nu bara om det fungerar i praktiken med?

Vanligaste sättet att stoppa sql injections (som jag sett) är genom att köra detta:
Kod:

$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user), mysql_real_escape_string($password));

mysql_query($query);

Den kommer dock ta massor av tid att ersätta denna med den ursprungliga koden.
Därför kom jag på ett annat alternativ, eftersom det är variablarna som kommer genom $_POST och $_GET som ska escapas, borde inte detta funka 100ggr bättre?

Kod:

// denna funktion placeras i en extern functions.php fil.
function e($str) {
  return mysql_real_escape_string($str)
}

$user = e($_POST['user']);
$pass = e($_POST['pass']);

$sql = "SELECT * FROM users WHERE user='$pass' AND password='$user';"
mysql_query($sql);

Kommer mitt sätt ens att fungera?
Kommer det fungera BRA? och är det tillräckligt säkert?
Varför använder alla den andra "tekniken" igentligen?

Hjälp mig!

mvh Jim

elofsson 2008-02-21 18:59

Dina varianter gör ju samma sak, bara två olika skrivsätt.

tartareandesire 2008-02-21 21:22

Citat:

Originally posted by elofsson@Feb 21 2008, 19:59
Dina varianter gör ju samma sak, bara två olika skrivsätt.

Mjo, enda skillnaden är att det blir mindre att skriva så på sätt och vis är det väl smidigare.

Jine 2008-02-21 21:28

Tack för svaren!
Så båda borde alltså fungera lika bra? =)

mvh Jim

elofsson 2008-02-21 21:36

Citat:

Originally posted by Jine@Feb 21 2008, 22:28
Så båda borde alltså fungera lika bra? =)
mvh Jim

Svar ja, funktionsmässigt.

Jine 2008-02-22 00:25

I form av prestanda och belastning då?

mvh Jim

JonathanJames 2008-02-22 01:50

Ingen skillnad, PHP-interpretern kommer tolka din kod och därmed också praktiskt ersätta (blir ju pekare till slut)varenda e($_POST['variabel']); med mysql_real_escape_string($_POST['variabel']);

Interpretern kommer inte att snurra några extravarv funktionsmässigt, funktionen är mer en estetisk grej för dig som programmerare.

Adam N 2008-02-22 07:33

Båda varianterna blir ju lite jobbiga om det är mer än bara user och password. Går det i PHP att
skriva någon generell funktion som loopar igenom alla POST-variabler och gör om dem? Jag kan
inte PHP, men tänkte mig alltså något i stil med...

Kod:

function mysql_real_escape_POST() {
  for_each variable in $_POST {
    variable = mysql_real_escape_string(variable)
  return mysql_real_escape_string($str)
}

...i en extern php-fil och sen är det bara att anropa denna funktion en gång i början av varje sida
där det behövs. Kanske går att konfigurera så att den anropas automatiskt till och med.

Någon som kan PHP får gärna rätta till detta exempel.

Sen vill man väl i vissa fall ge ett tydligt felmeddelande istället för att exekvera SQL-satsen om
någon skickar otillåtna tecken. Detta bör i så fall göras på både serversidan och klientsidan.

Jonas 2008-02-22 07:39

Ta en titt på MySQLi och Prepared Statements, mycket säkrare.

Lumax 2008-02-22 08:34

Citat:

Originally posted by Adam N@Feb 22 2008, 08:33
Båda varianterna blir ju lite jobbiga om det är mer än bara user och password. Går det i PHP att
skriva någon generell funktion som loopar igenom alla POST-variabler och gör om dem? Jag kan
inte PHP, men tänkte mig alltså något i stil med...

Kod:

function mysql_real_escape_POST() {
  for_each variable in $_POST {
    variable = mysql_real_escape_string(variable)
  return mysql_real_escape_string($str)
}

...i en extern php-fil och sen är det bara att anropa denna funktion en gång i början av varje sida
där det behövs. Kanske går att konfigurera så att den anropas automatiskt till och med.

Någon som kan PHP får gärna rätta till detta exempel.

Sen vill man väl i vissa fall ge ett tydligt felmeddelande istället för att exekvera SQL-satsen om
någon skickar otillåtna tecken. Detta bör i så fall göras på både serversidan och klientsidan.

Du kan lägga in följande kod i "header.php" eller motsvarande.
Kod:

if (get_magic_quotes_gpc()) {
  $_GET = array_map("stripslashes", $_GET);
  $_POST = array_map("stripslashes", $_POST);
}

$_GET = array_map("mysql_real_escape_string", $_GET);
$_POST = array_map("mysql_real_escape_string", $_POST);


hallis 2008-03-02 16:16

Du behöver inte escape'a varje enskild POST-/GET-värde.
Citat:

$_POST = mysql_real_escape_string($_POST);
$_GET = mysql_real_escape_string($_GET);


Magnus_A 2008-03-02 17:57

mysql(i)_real_escape_string($varlabel,$link_identi fier) heter det,
där $link_identifier är en handler till en uppkoppling av databasen. Om man inte skickar med den så kan det bli fel.

Lumax 2008-03-02 23:09

Citat:

Originally posted by Magnus_A@Mar 2 2008, 18:57
mysql(i)_real_escape_string($varlabel,$link_identi fier) heter det,
där $link_identifier är en handler till en uppkoppling av databasen. Om man inte skickar med den så kan det bli fel.

Enbart om man har flera kopplingar, då används den senaste.

Adam N 2008-03-03 04:58

Citat:

Ursprungligen postat av Fredrik S
Citat:

Ursprungligen postat av Magnus_A
mysql(i)_real_escape_string($varlabel,$link_identi fier) heter det,
där $link_identifier är en handler till en uppkoppling av databasen. Om man inte skickar med den så kan det bli fel.

Enbart om man har flera kopplingar, då används den senaste.

Förstår inte på vilket sätt det kan bli fel. Exempel? :unsure:

Lumax 2008-03-03 10:35

mysql(i)_real_escape_string() fungerar lite olika beroende på vilken teckentabell databasen använder. Vilka tecken som anses "problematiska" är alltså olika beroende på ISO-8859-1 och UTF-8 t.ex.
Så om du har två anslutningar mot olika databaser som kör olika charsets så kan du få situationer där SQL-injections är möjliga om du inte hänvisar till rätt databasanslutning när du kör mysql(i)_real_escape_string().

Detta är dock väldigt ovanligt eftersom det flesta enbart har en databas som scriptet jobbar mot, och i de fall man har flera databaser så har dessa i oftast samma charset.

Men visst, Magnus_A har en poäng. Det är skadar inte att ta med link identifier.

Magnus_A 2008-03-03 10:49

Citat:

Ursprungligen postat av Adam N
Citat:

Originally posted by -Fredrik S@Mar 2 2008, 23:09
Citat:

Ursprungligen postat av Magnus_A
mysql(i)_real_escape_string($varlabel,$link_identi fier) heter det,
där $link_identifier är en handler till en uppkoppling av databasen. Om man inte skickar med den så kan det bli fel.

Enbart om man har flera kopplingar, då används den senaste.


Förstår inte på vilket sätt det kan bli fel. Exempel? :unsure:

Typiskt felmeddelande om man inte skriver rätt:

<?php
echo mysqli_real_escape_string('hej');
?>
Utan föregående uppkoppling så försöker php logga in utan lösenord, sällan en bra ide:
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Användare 'www-data'@'localhost' är ej berättigad att logga in (Använder lösen: NO) in /var/www/*** on line *

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /var/www/**** on line *

Och för mysqli:

Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in /var/www****


Alla tider är GMT +2. Klockan är nu 21:51.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson