[PHP] leren securen voor SQL injections

Pagina: 1
Acties:
  • 108 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • apNia
  • Registratie: Juli 2002
  • Laatst online: 08:54

apNia

Schreeuwen en Nibbits eten!

Topicstarter
Hey tweakers.. ben op het moment mezelf aan het aanleren te securen tegen mySQL injections. Nou zat ik wat te pielen met een oude foutieve query van mij, namelijk de volgende:

PHP:
1
2
3
4
5
6
7
   if($_SERVER['REQUEST_METHOD'] == "POST" && !empty($_POST['dellist'])){
    $dellist = $_POST['dellist'];
    for($i = 0; $i < sizeof($dellist); $i++){
        mysql_query("DELETE FROM columns WHERE col_id = '".$dellist[$i]."'");
        mysql_query("DELETE FROM comments WHERE col_id = ". $delist[$i]);
    }
   }

Nu is het mogelijk gewoon lokaal via een HTML dit script remote aan te spreken via een form met bijvoorbeeld een value
PHP:
1
<INPUT id="checkbox" type="checkbox" name="dellist[]" value="1337" checked>


Nou zit het probleem hem voornamelijk in de 2 query. Ik kan wel de comment deleten waar col_id = 1337 nu dus. Dus dat snap ik. Maar zo zijn er ook een aantal met col_id = NULL in de table. Maar als ik er van maak
PHP:
1
value="1337 OR col_id IS NULL"
dan pikt hij dat niet. Ook als 1337 al niet meer bestaat. Wat tevens niet werkt is bijvoorbeeld
PHP:
1
value="1337 OR id=1"
(note verschil tussen eerst col_id en nu id AKA de PK)

Ik sta echt voor een raadsel, wat ik doe lijkt niet via een OR oid te appenden zijn. Zelfs als ik er value="NULL" van maak werkt het niet..

Iemand enig idee waarom? GoT en google konden me search-gewijs niet van dienst zijn ;)

[ Voor 9% gewijzigd door apNia op 07-12-2005 10:50 ]


Acties:
  • 0 Henk 'm!

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Zoek eens naar:

code:
1
AddSlashes()

code:
1
mysql_quote()


Of wacht, dat is volgens mij je probleem niet 8)7

Jij hebt juist dat je SQL Injections WILT hebben.

[ Voor 49% gewijzigd door Infinitive op 07-12-2005 10:45 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


Acties:
  • 0 Henk 'm!

  • apNia
  • Registratie: Juli 2002
  • Laatst online: 08:54

apNia

Schreeuwen en Nibbits eten!

Topicstarter
Jep, dat wil ik juist dat allemaal snappen. Want ik snap mySQL injections for one reason or another niet echt.
Als ik dus dit doe:
<INPUT id="checkbox" type="checkbox" name="dellist[]" value="13 OR col_id IS NULL" checked>

Krijg ik wel netjes dit terug...
Array ( [0] => 13 OR col_id IS NULL )

Waarom pikt PHP dit nou gewoon niet en delete ie niet waar de de col_id NULL is?

Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Print je query eens.

March of the Eagles


Acties:
  • 0 Henk 'm!

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Hint: output je sql-query eens, dan zie je wat er mis gaat :)
(namelijk dat een deel van de query als string wordt aangezien. Bij een sql injection gebruik je meestal wat truukjes om uit zo'n string te ontsnappen).

Waarschijnlijk als je:
code:
1
13' OR col_id IS NULL OR col_id='blaat


invult dan doet 'ie het wel. Als magic sql quotes niet aan staan tenminste.

[ Voor 9% gewijzigd door Infinitive op 07-12-2005 10:57 . Reden: double quotes to single quotes ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


Acties:
  • 0 Henk 'm!

  • sorted.bits
  • Registratie: Januari 2000
  • Laatst online: 06:49
Wat ik altijd doe is eerst de query even in een string zetten (dus samen gesteld) en dan kijken of je wel kan runnen in PHPMyAdmin (bijvoorbeeld).

Werkt dat wel?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Infinitive schreef op woensdag 07 december 2005 @ 10:44:
Zoek eens naar:

code:
1
AddSlashes()

code:
1
mysql_quote()


Of wacht, dat is volgens mij je probleem niet 8)7

Jij hebt juist dat je SQL Injections WILT hebben.
Voor mysql kan je veel beter gebruik maken van mysql_real_escape()

Het idee is eigenlijk heel eenvoudig. Als je iets als een getal in je query probeert te inserten moet je eerst controleren of het wel een getal is. Als je een string in je query probeert te gebruiken moet je zorgen dat mysql het ook als een string ziet.

Standaard is dat tussen ' '. Maar daar kan de gebruiker dan omheen omdat hij natuurlijk ook gewoon een ' in zijn query kan typen. Hiervoor zul je moeten escapen. Voor mysql gebruik je daarvoor het best de functie mysql_real_escape() deze vangt alle speciale characters af.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • WormLord
  • Registratie: September 2003
  • Laatst online: 01-08 12:04

WormLord

Devver

Heb je misschien een foreign-key tussen naar de comments-tabel toe die je deletes blokkeerd?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

WormLord schreef op woensdag 07 december 2005 @ 12:43:
Heb je misschien een foreign-key tussen naar de comments-tabel toe die je deletes blokkeerd?
Het gaat hier over MySQL, niet over een RDBMS ;).

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!

  • bakkerl
  • Registratie: Augustus 2001
  • Laatst online: 01-09 19:17

bakkerl

Let there be light.

PHP PEAR gebruiken met de DB package

PHP:
1
2
3
4
5
6
7
8
$sql = "DELETE FROM table1 WHERE id=? and id2=?";
$sqldata = array($_POST["id"], $_GET["id2"]);
# evenveel elementen in de array als ? in de query string. Mogen alle types door elkaar heen zijn.

$db = DB::connect($connectstring)
$db->Query($sql, $sqldata);

# resultaten en fout afhandeling verder...


doet meteen de addslashes en alles wat er nodig is. Bij string worden er '' omheen gezet, getallen laat die gewoon staan, en alles wordt natuurlijk netjes geslashed en ge-escaped waar dat nodig is.

[ Voor 17% gewijzigd door bakkerl op 07-12-2005 13:52 . Reden: escaped opmerking erbij ]


Acties:
  • 0 Henk 'm!

  • DizzyWeb
  • Registratie: Februari 2001
  • Laatst online: 05-09 14:30

DizzyWeb

Ondertiteld

De meesten lezen niet goed. Hij wil geen injection voorkomen, hij wil JUIST een injection MAKEN!

Zoals gezegd is: print de query eens in plaats van 'm uit te voeren.

Acties:
  • 0 Henk 'm!

  • MaNdM
  • Registratie: April 2001
  • Laatst online: 09:04

MaNdM

1000-dingen-doekje

Janoz schreef op woensdag 07 december 2005 @ 13:43:
[...]

Het gaat hier over MySQL, niet over een RDBMS ;).
Bij gebruik van InnoDB tabellen kan je wel degelijk FK's aanmaken met cascades en dan spreek je toch echt van een RDBMS ;)

To be determined...


Acties:
  • 0 Henk 'm!

Verwijderd

Dit iets voor je?
KayRa: http://sourceforge.net/projects/kayra
KayRa is a Web Application Security Auditing Tool designed to test the security of websites by analyzing web pages. Some of the tests include: SQL Injection, XSS, Form behaviour with bad data. All tests carried out will be based on the OWASP guide.

Acties:
  • 0 Henk 'm!

  • Thralas
  • Registratie: December 2002
  • Laatst online: 24-08 21:46
Infinitive schreef op woensdag 07 december 2005 @ 10:56:
Hint: output je sql-query eens, dan zie je wat er mis gaat :)
(namelijk dat een deel van de query als string wordt aangezien. Bij een sql injection gebruik je meestal wat truukjes om uit zo'n string te ontsnappen).

Waarschijnlijk als je:
code:
1
13' OR col_id IS NULL OR col_id='blaat


invult dan doet 'ie het wel. Als magic sql quotes niet aan staan tenminste.
Simpeler is -- aan het eind van de string te appenden, alles erna wordt gezien als comment. Raar dat IS NULL niet werkt, weet je zeker dat de velden null zijn en niet ""?
Ik neem aan dat
SQL:
1
OR 1=1--
wel werkt?

Volgens mij zul je per request maar bij één van de twee queries kunnen injecten, aangezien de ene quotes heeft, en de ander niet.

[ Voor 3% gewijzigd door Thralas op 07-12-2005 17:32 ]


Acties:
  • 0 Henk 'm!

  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 10-09 21:59
apNia schreef op woensdag 07 december 2005 @ 10:41:
PHP:
1
2
3
4
5
6
7
   if($_SERVER['REQUEST_METHOD'] == "POST" && !empty($_POST['dellist'])){
    $dellist = $_POST['dellist'];
    for($i = 0; $i < sizeof($dellist); $i++){
        mysql_query("DELETE FROM columns WHERE col_id = '".$dellist[$i]."'");
        mysql_query("DELETE FROM comments WHERE col_id = ". $delist[$i]);
    }
   }

en
PHP:
1
value="1337 OR col_id IS NULL"
oftewel je queries worden

SQL:
1
2
DELETE FROM columns WHERE col_id = '1337 or col_id IS NULL';
DELETE FROM comments WHERE col_id = 1337 or col_id IS NULL;

beide queries zijn dus fout

de manier om de sql injection te doen is zoals Infinitive reeds gezegd heeft.

[ Voor 42% gewijzigd door DamadmOO op 07-12-2005 23:41 ]


Acties:
  • 0 Henk 'm!

Verwijderd

MaNdM schreef op woensdag 07 december 2005 @ 17:17:
Bij gebruik van InnoDB tabellen kan je wel degelijk FK's aanmaken met cascades en dan spreek je toch echt van een RDBMS ;)
Nee niet van een echt hoor. De keys fucken nog steeds up bij een serieuze load...

Acties:
  • 0 Henk 'm!

  • MaNdM
  • Registratie: April 2001
  • Laatst online: 09:04

MaNdM

1000-dingen-doekje

Verwijderd schreef op donderdag 08 december 2005 @ 00:36:
[...]

Nee niet van een echt hoor. De keys fucken nog steeds up bij een serieuze load...
Als je kijkt naar versie 5 dan spreken we toch echter wel van een RDBMS...

To be determined...

Pagina: 1