[PHP] SQL Injection met Magic Quotes aan?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • willem-alex
  • Registratie: December 2001
  • Laatst online: 18-05-2024

willem-alex

you don't wanna know ...

Topicstarter
Op php.net lees ik het volgende:
Why use Magic Quotes
- Useful for beginners
Magic quotes are implemented in PHP to help code written by beginners from being dangerous. Although SQL Injection is still possible with magic quotes on, the risk is reduced.
Weet iemand hier het fijne van, ik kan er verder namelijk nergens iets over vinden. Ik ben namelijk benieuwd of iemand in het volgende scriptje kan komen terwijl magic quotes aan staat:

code:
1
2
3
$query = "SELECT username FROM leden 
WHERE password = password('$PHP_AUTH_PW') 
AND username = '$PHP_AUTH_USER' ";

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

Ja hoor. Heel makkelijk. Aangenomen dat het hier om magic_quotes_gpc gaat.

http://nl3.php.net/manual/en/security.magicquotes.php

Hierbij worden alleen de GET, POST en COOKIE vars geescaped.


Sowieso vind ik het een beetje een ruk instelling. Je moet eigenlijk gewoon zelf nadenk waar je mee bezig bent. Op dit moment heb ik in veel scripts van me weer allemaal if's staan om eventueel te unescapen waneer de setting aanstaat.

[ Voor 90% gewijzigd door Janoz op 03-02-2005 16:04 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Oke, maar stel je maakt alleen paginas voor op je eigen server, waar dus magic_quoates_gpc aan staat. En je gebruikt de volgende code:

PHP:
1
2
3
$query = "SELECT `username` FROM `leden` 
WHERE `password` = '".$_POST['password']."' 
AND `username` = '".$_POST['username']."' ";


Is het dan nogsteeds zo onveilig?

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

Dan is het inderdaad veilig. Maar alleen omdat je zelf weet dat je ook de magic_quotes aan hebt staan op je eigen server. Aan dit stukje code zelf is dat niet te zien!

Ik vind het in mijn programmeer ogen heel logisch is om hier juist expliciet een escape slag te doen. We zijn immers een sting met een comando aan het opbouwen. Stel je wilt een email opmaken of er komt iemand op het lumineuze idee om geparameteriseerde queries te implementeren. Dan moet je vervolgens overal onbegrijpelijke stripslashes toe gaan passen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • willem-alex
  • Registratie: December 2001
  • Laatst online: 18-05-2024

willem-alex

you don't wanna know ...

Topicstarter
Janoz schreef op donderdag 03 februari 2005 @ 16:00:
Hierbij worden alleen de GET, POST en COOKIE vars geescaped.
Dus wat je bedoelt is dat als je data op een andere manier in de query krijgt, je nog wel ongewenste resultaten kan krijgen. Ik vraag me dan af, wélke andere manieren heb je nog die een 'indringer' kan gebruiken?? SESSION lijkt me uitgesloten of niet.

De variabelen zijn trouwens globals. Het is een site die ik een tijd geleden gemaakt heb, nu gebruik ik geen globals meer ;)

Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Klopt. Ik ben ook helemaal voor het zelf escapen.

Maar wij hebben hier nog wel een aantal websites waar bovenstaand stukje code in gebruikt wordt, wat dus draaid op onze server met magic_quotes, en ik twijfelde opeens even of dat dan ook onveilig zou zijn. :)

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:21

crisp

Devver

Pixelated

Janoz schreef op donderdag 03 februari 2005 @ 16:00:
Ja hoor. Heel makkelijk. Aangenomen dat het hier om magic_quotes_gpc gaat.

http://nl3.php.net/manual/en/security.magicquotes.php

Hierbij worden alleen de GET, POST en COOKIE vars geescaped.
Niet helemaal; waarden 'van buiten' in de $_SERVER superglobal worden ook escaped ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • pjonk
  • Registratie: November 2000
  • Laatst online: 10-09 15:33
Janoz schreef op donderdag 03 februari 2005 @ 16:00:
Sowieso vind ik het een beetje een ruk instelling. Je moet eigenlijk gewoon zelf nadenk waar je mee bezig bent. Op dit moment heb ik in veel scripts van me weer allemaal if's staan om eventueel te unescapen waneer de setting aanstaat.
Yups ;)
[rml]JonkieXL in "[ PHP] Gebruik GET variabele in SQL query"[/rml]

It’s nice to be important but it’s more important to be nice


Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Met magic quotes aan kunnen er toch nog kwetsbaarheden zijn als je je input niet valideert.
Een voorbeeld is bijvoorbeeld registreren met een username met een quote er in.
Door magic quotes wordt dit goed ge-insert, als deze username dan echter weer uit de database gehaald wordt en ergens in een query wordt gebruikt dan is die query weer te manipuleren.
Dit komt nogal eens voor bij password update functionaliteit.

Who is John Galt?


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

@crisp

En dat is nu zo mooi aan php. Ze weten zelf niet eens wat ze doen blijkbaar. Uit de manual haal ik dat niet. iig niet bij de beschrijving van magic quotes, en ook niet bij het onderdeel over HTTP_AUTH.

[ Voor 13% gewijzigd door Janoz op 03-02-2005 16:34 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Janoz schreef op donderdag 03 februari 2005 @ 16:00:
Op dit moment heb ik in veel scripts van me weer allemaal if's staan om eventueel te unescapen waneer de setting aanstaat.
Je bent sneller door gewoon even dit te doen aan het begin:
PHP:
1
2
if (get_magic_quotes_gpc() == 1)
    ini_set("get_magic_quotes_gpc", 0);

Acties:
  • 0 Henk 'm!

  • willem-alex
  • Registratie: December 2001
  • Laatst online: 18-05-2024

willem-alex

you don't wanna know ...

Topicstarter
justmental schreef op donderdag 03 februari 2005 @ 16:28:
Met magic quotes aan kunnen er toch nog kwetsbaarheden zijn als je je input niet valideert.
Een voorbeeld is ...
Dus het zou kunnen dat dit probleem zich voordoet bij het updaten van passwords, maar als ik het goed begrijp moet je daarvoor wel eerst een account hebben. Ik ben meer geïnteresseerd in de vraag of je er zonder account met alleen twee veldjes (username en password) toch in komt.

Acties:
  • 0 Henk 'm!

  • pierre-oord
  • Registratie: April 2002
  • Laatst online: 10-02 23:00
marty schreef op donderdag 03 februari 2005 @ 16:39:
[...]


Je bent sneller door gewoon even dit te doen aan het begin:
PHP:
1
2
if (get_magic_quotes_gpc() == 1)
    ini_set("get_magic_quotes_gpc", 0);
Ben je dan niet al te laat? Immers ben je al in je script aangekomen, en zouden alle POST/GET etc vars al moeten zijn ge-escaped. Ook weet ik niet of je zomaar rechten hebt om dit altijd in te stellen.

Acties:
  • 0 Henk 'm!

  • pjonk
  • Registratie: November 2000
  • Laatst online: 10-09 15:33
@Marty: Werkt dit dan? Heb gelezen dat dit niet werkt, omdat de slashes er al zijn op het punt dat jij de magic_quotes setting uitzet. Maw je bent te laat met uitzetten. (maybe dat jouw methode wel werkt in nieuwere PHP versies?)

It’s nice to be important but it’s more important to be nice


Acties:
  • 0 Henk 'm!

Verwijderd

OkkE schreef op donderdag 03 februari 2005 @ 16:08:
Oke, maar stel je maakt alleen paginas voor op je eigen server, waar dus magic_quoates_gpc aan staat. En je gebruikt de volgende code:

PHP:
1
2
3
$query = "SELECT `username` FROM `leden` 
WHERE `password` = '".$_POST['password']."' 
AND `username` = '".$_POST['username']."' ";


Is het dan nogsteeds zo onveilig?
Niet helemaal. Je moet echt de waarden nog controleren. Even zoeken naar %20OR%201=1 op google bracht me bij dit. %20 is een spatie. Er wordt dus het volgende aan je sql toegevoegd " OR 1=1" En omdat 1 altijd gelijk is aan 1 stuurt sql alles terug.

Even deze link maar eens lezen lijkt me http://www.summercon.org/2004/SQLInjectionSlides.pdf

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

@Marty: Dat werkt niet. Waar die code al staat, het escapen is al gebeurt. Dat gebeurt immers vlak voordat je script uberhaupt wordt verwerkt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • willem-alex
  • Registratie: December 2001
  • Laatst online: 18-05-2024

willem-alex

you don't wanna know ...

Topicstarter
Haha wel leuk dit zo'n hele discussie rond iets waar mijn vraag niet eens zozeer over ging :D
Toch hoop ik dat jullie me wel kunnen helpen.
Kunnen jullie me vertellen of er een mogelijkheid bestaat dat je zonder account met alleen twee veldjes (username en password) toch in de site komt met het allerbovenste scriptje. Ik weet dat het niet mag: maar alvast bedankt ;)

Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

code:
1
2
3
$query = "SELECT username FROM leden 
WHERE password = password('$PHP_AUTH_PW') 
AND username = '$PHP_AUTH_USER' ";

Dat ligt helemaal aan die $PHP_AUTH_PW en $PHP_AUTH_USER.
Waar komen die vandaan en hoe zijn die gecontroleerd?
Type eens een quotje in het username veld en submit het form.
Knalt je select met een foutmelding dan ben je kwetsbaar, anders niet.
moet wel je foutafhandeling aan staan natuurlijk

[ Voor 12% gewijzigd door justmental op 03-02-2005 17:32 ]

Who is John Galt?


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:21

crisp

Devver

Pixelated

Janoz schreef op donderdag 03 februari 2005 @ 16:30:
@crisp

En dat is nu zo mooi aan php. Ze weten zelf niet eens wat ze doen blijkbaar. Uit de manual haal ik dat niet. iig niet bij de beschrijving van magic quotes, en ook niet bij het onderdeel over HTTP_AUTH.
Inderdaad, het wordt nergens beschreven Dat is de reden dat ik het eens heb uitgetest. Het maakt wel de verwarring alleen maar groter, want op het moment dat je denkt dat magic_quotes wel uit kan omdat je netjes al je GET, POST en COOKIE vars zelf afhandeld ga je alsnog de boot in als je ergens de $_SERVER['HTTP_USER_AGENT'] in een query stopt :)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

Dat maakt het alleen nog maar irritanter aangezien het
1. Nergens is terug te vinden in de manual.
2. Niet eens af te leiden is uit de propertie naam (waar immers gpc in voorkomt).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • commeric
  • Registratie: November 2002
  • Laatst online: 14-08 22:32
Het handigste om te doen is (wanneer magic quotes aan staan) alles te unescapen. En vervolgens zelf variables weer te escapen?

bijvoorbeeld


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?PHP

function cleanArray(&$arr) 
{
   foreach($arr as $k => $v)
           if (is_array($v))
                   cleanArray($arr[$k]);
           else
                   $arr[$k] = stripslashes($v);
}

if (get_magic_quotes_gpc() == 1) 
{


   /// before processing anything in PHP do
   if (get_magic_quotes_gpc()) {
     cleanArray($_POST);
     cleanArray($_COOKIE);
     cleanArray($_GET);
   }
  }



// En vervolgens 
$_POST['username'] = addslashes($_POST['username']);
$_POST['password'] = addslashes($_POST['password']);


//En dan


$query = "SELECT `username` FROM `leden`  
WHERE `password` = '$_POST[password]'  
AND `username` = '$_POST[username]' "; 

?>

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

in principe is het gevaar voor SQL injection injection niet helemaal geweken met alleen magic quotes inderdaad :

Stel een voorbeeldje waar je niet met een username, maar met een userid (een integer) inlogt :
PHP:
1
$query = "SELECT * FROM users WHERE userid = " . $_REQUEST['userid']." AND password = '". $_REQUEST['password'] . "'";


Dan staan er géén quotes om de userid, en kan er nog steeds geinjecteerd worden :

PHP:
1
2
3
4
5
6
7
$_REQUEST['userid'] = "1 OR 1=1";
$_REQUEST['password'] = 'blaat';

$query = "SELECT * FROM users WHERE userid = " . $_REQUEST['userid']." AND password = '". $_REQUEST['password'] . "'";

// Nu is $query : 
// SELECT * FROM users WHERE userid = 1 OR 1=1 AND password = '". $_REQUEST['password'];

En dat gaat een record opleveren als userid 1 tenminste bestaat.

In dit soort situaties converteer ik de userinput altijd naar een int. Zo is de boel wel veilig :

PHP:
1
$query = "SELECT * FROM users WHERE userid = " .((int) $_REQUEST['userid']) ." AND password = '". $_REQUEST['password'] . "'";


Natuurlijk kan je ook gewoon al je velden bruut als string opgeven, dus quoten, dan gaat het ook goed, en converteert MySQL de boel wel naar een int als het vergeleken wordt met een integer.

Acties:
  • 0 Henk 'm!

  • Dutchmega
  • Registratie: September 2001
  • Niet online
eamelink schreef op dinsdag 19 april 2005 @ 17:36:
in principe is het gevaar voor SQL injection injection niet helemaal geweken met alleen magic quotes inderdaad :

Stel een voorbeeldje waar je niet met een username, maar met een userid (een integer) inlogt :
PHP:
1
$query = "SELECT * FROM users WHERE userid = " . $_REQUEST['userid']." AND password = '". $_REQUEST['password'] . "'";


Dan staan er géén quotes om de userid, en kan er nog steeds geinjecteerd worden :

PHP:
1
2
3
4
5
6
7
$_REQUEST['userid'] = "1 OR 1=1";
$_REQUEST['password'] = 'blaat';

$query = "SELECT * FROM users WHERE userid = " . $_REQUEST['userid']." AND password = '". $_REQUEST['password'] . "'";

// Nu is $query : 
// SELECT * FROM users WHERE userid = 1 OR 1=1 AND password = '". $_REQUEST['password'];

En dat gaat een record opleveren als userid 1 tenminste bestaat.

In dit soort situaties converteer ik de userinput altijd naar een int. Zo is de boel wel veilig :

PHP:
1
$query = "SELECT * FROM users WHERE userid = " .((int) $_REQUEST['userid']) ." AND password = '". $_REQUEST['password'] . "'";


Natuurlijk kan je ook gewoon al je velden bruut als string opgeven, dus quoten, dan gaat het ook goed, en converteert MySQL de boel wel naar een int als het vergeleken wordt met een integer.
MySQL werkt prima met quotes om integers heen dus extra integers kunnen gaan kwaad :)
Ik gebruik trouwens een class waarbij je alle gegevens via $_POST, $_GET, $_SERVER etc. ophaalt via een functie en als het nodig is: automatisch stripslashes(); Daarnaast heb ik een MySQL die automatisch spullen regelt zoals quotes en meer zodat je ook niet meer quotes kunt vergeten :)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Btw, het gaat bij MySQL dan wel goed, maar dat is een van de weinige databases die ik ken die de ' met \' geescaped accepteert... PostgreSQL en vele andere databases gebruiken gewoon de SQL-spec-variant en die werkt door ' met nog een ' te escapen ('' dus). Dus daarbij ben je sowieso niet veilig, tenzij je dan weer magic_quotes_sybase aanzet, maar dat staat standaard uiteraard uit.

Acties:
  • 0 Henk 'm!

  • Suepahfly
  • Registratie: Juni 2001
  • Laatst online: 04-09 16:39
pierre-oord schreef op donderdag 03 februari 2005 @ 16:45:
[...]


Ben je dan niet al te laat? Immers ben je al in je script aangekomen, en zouden alle POST/GET etc vars al moeten zijn ge-escaped. Ook weet ik niet of je zomaar rechten hebt om dit altijd in te stellen.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
set_magic_quotes_runtime (0); 
if (get_magic_quotes_gpc() == 1) 
{ 
    if (isset ($_GET)) 
        array_walk ($_GET, "stripslashesHelper"); 
    if (isset ($_POST)) 
        array_walk ($_POST, "stripslashesHelper"); 
    if (isset ($_COOKIE)) 
        array_walk ($_COOKIE, "stripslashesHelper"); 
    if (isset ($_REQUEST)) 
        array_walk ($_REQUEST, "stripslashesHelper"); 
} 


function stripslashesHelper (&$v) 
{ 
    if (is_array ($v)) 
        array_walk ($v, "stripslashesHelper"); 
    else 
        $v = stripslashes ($v); 
}

Bovenstaande snippet (met dank aan .oisyn) zet j magic_quotes uit en stript de quotes
edit:
Ik moet leren het hele topic te lezen :/

[ Voor 7% gewijzigd door Suepahfly op 19-04-2005 22:42 ]

Pagina: 1