[PHP] framework: waar injection voorkomen?

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
Ik ben in m'n vrije tijd een php-framework aan het schrijven dat onder andere iets EJB-achtigs moet doen.
In de eerste instantie wilde ik alleen een dotProject'++' maken, maar omdat ik toch nog een half programmeerseltje had liggen ben ik dat gaan verbeteren 8)
Op dit moment ben ik aan het bekijken hoe en waar ik de beveiliging wil toepassen; voor het gemak alleen even het voorkomen van sql-injection.

Mijn model bestaat uit de volgende lagen:
code:
1
2
3
4
5
6
7
8
9
presentatielaag (webpages)
       |
  controlelaag (controllers voor webpages)
       |
   modellaag (classes, begin van m'n framework)
       |
   abstractie (vertaalt de classes naar db-classes ed)
       |
   databaselaag (vertaalt de db-classes naar queries)


Concreet vraag ik me af: op welke plaats kun je het beste controleren op injection?
Wat ik zelf bedacht heb maar nog niet weet wat het beste is:
  1. op elke laag
  2. alleen op de twee bovenste lagen -1 (controlelaag en abstractielaag)
  3. alleen op de onderste laag
Ik geloof dat alle opties werken, alleen:
  1. Lijkt me een overkill, maar ook weer niet (ooit worden deze lagen misschien wel uit elkaar getrokken)
  2. Leuk voor m'n eigen situatie, maar wat nou als iemand alleen de databaselaag gaat gebruiken?
  3. Werkt altijd, maar moet je helemaal tot in die laag wachten met het geven van een foutmelding? Gebruikers kunnen dan al lang heel ergens anders mee bezig zijn omdat het fysiek opslaan van data in de database niet perse direct na het verzoek van de gebruiker hoeft te gebeuren.
Ik heb GoT erbij gehaald om voor me te kijken of er al mensen waren met hetzelfde probleem, maar de gevonden resultaten zijn veel te specifiek, of geven alleen maar antwoord op hoe-voorkom-ik-sql-injection. Ook google is niet erg behulpzaam omdat daar ook alleen beschrijvingen uitkomen hoe je het moet implementeren.. Dus als iemand hier een mening over heeft _/-\o_

Acties:
  • 0 Henk 'm!

  • aOk
  • Registratie: September 2000
  • Niet online

aOk

gewoon bij de input van POST en GETS :S en eventueel cookies.

[ Voor 22% gewijzigd door aOk op 04-08-2007 13:19 ]


Acties:
  • 0 Henk 'm!

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
en dan ga ik m'n framework los van de site gebruiken: compleet kwetsbaar; zit ik ook niet op te wachten...

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Ik zou voor de laatste optie gaan, net als bij de omgekeerde weg. Als je data ophaalt ga je de gegevens ook pas aanpassen (bijv, heel makkelijk, alles lowercase of de eerste letter uppercase e.d.) in je laatste laag.
In mijn eigen framework (hoewel het niet echt een framework is) heb ik in de modellaag een fout-object zitten die de fouten kan afvangen. Wat je kan doen is de db-laag de injectie laten afvangen, die het vervolgens terugkoppelt (met of zonder tussenkomst van je abstractielaag) naar je modellaag. Dan kunnen de lagen die daar weer bovenop zitten de fouten uit je errorobject halen en er mee doen wat ze willen, naar gelang de "ernst" van de opgeslagen fout.

Acties:
  • 0 Henk 'm!

  • Thralas
  • Registratie: December 2002
  • Laatst online: 24-08 21:46
Ik snap het probleem niet? Je zorgt gewoon in je databaselaag dat je alle variabele input escaped (strings) of checkt dmv. is_numerc (ints/floats)? Wat voor class er dan ook 'door' de databaselayer gaat, er kan niets fout gaan?

Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 21:16
Eens met Thralas. Je hoeft geen foutmelding te geven bij SQL injection. Stel je heb een forum op een site en iemand typt in dat forum in:
Goed idee, mee eens!');DROP TABLE forum;
Als jij er voor zorgt dat deze string netjes ge-escaapt wordt voordat het in een SQL statement terecht komt, dan is er niets aan de hand. Je hoeft de gebruiker niet te vertellen dat DROP TABLE niet toegestaan is ofzo.

escapen zou ik doen op het moment dat de feitelijke query in elkaar gezet wordt.

Acties:
  • 0 Henk 'm!

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
@mithras: dat lijkt me inderdaad een prima optie, ga ik ook eens proberen!

@Thralas && rutgerw: Het werkt inderdaad altijd als je die controles in je onderste laag zet, maar wat nou als iemand de bovenste helft van die lagen gaat gebruiken (die ook een losstaand onderdeel van m'n framework worden, als cms) zonder de onderste laag? Dan is het niet gegarandeerd veilig. Dat is m'n probleem :+

Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 10-09 16:00

kokx

WIN

Daar worden er als het goed is toch geen query's uitgevoerd, dus wat voor probleem heb je dan? En als hij dat wel gaat doen is het toch z'n eigen schuld?

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Mjah, uiteindelijk zul je zien dat het ergens moet gebeuren op de plek waar je iets doet als

PHP:
1
2
$user->set('username', $_REQUEST['username']);
$user->set('created', 'NOW()');


Hier maak je het verschil tussen een string en bijvoorbeeld een functie, die niet ge-escaped hoeft te worden :). Ik pak dan meestal gewoon een boolean $escape :

PHP:
1
2
$user->set('username', $_REQUEST['username']); // Standaard wel escapen
$user->set('created', 'NOW()', false); // Deze niet escapen


En dat bevalt altijd prima :)

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
rutgerw schreef op zaterdag 04 augustus 2007 @ 13:43:
Eens met Thralas. Je hoeft geen foutmelding te geven bij SQL injection. Stel je heb een forum op een site en iemand typt in dat forum in:

[...]


Als jij er voor zorgt dat deze string netjes ge-escaapt wordt voordat het in een SQL statement terecht komt, dan is er niets aan de hand. Je hoeft de gebruiker niet te vertellen dat DROP TABLE niet toegestaan is ofzo.

escapen zou ik doen op het moment dat de feitelijke query in elkaar gezet wordt.
Wat je nu dus doet is de presentatie bepalen in de database laag. Terwijl dat dus eigenlijk je fundamentele laag moet zijn die veel informatie terugkoppelt naar bovenliggende lagen. Als je als website-bouwer uiteindelijk bepaalt om op een forum de sql-injectie niet te tonen, moet dat kunnen. Als ik echter in een totaal andere webapplicatie bepaal dat het wél moet kunnen, zit je met de gebakken peren als je framework het niet meer ondersteund.

Het toch invoeren van de ge-escapede data ligt los van het feit dat je terugkoppeling wilt hebben. Bij voorkeur naar een aparte error-constructie (een laag of object, dat is je eigen keuze). Of je die fouten vervolgens uit dat object gaat gebruiken is hier niet aan de order :)
eamelink schreef op zaterdag 04 augustus 2007 @ 13:51:
Mjah, uiteindelijk zul je zien dat het ergens moet gebeuren op de plek waar je iets doet als

PHP:
1
2
$user->set('username', $_REQUEST['username']);
$user->set('created', 'NOW()');


Hier maak je het verschil tussen een string en bijvoorbeeld een functie, die niet ge-escaped hoeft te worden :). Ik pak dan meestal gewoon een boolean $escape :

PHP:
1
2
$user->set('username', $_REQUEST['username']); // Standaard wel escapen
$user->set('created', 'NOW()', false); // Deze niet escapen


En dat bevalt altijd prima :)
En wat als je nu een modulair systeem hebt waarbij verschillende mensen aan je framework werken. Gaat persoon 1 in laag a escapen, persoon 2 in laag b en je krijgt daardoor juist gaten of dubbele escaping ;)

[ Voor 24% gewijzigd door mithras op 04-08-2007 13:53 ]


Acties:
  • 0 Henk 'm!

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
@kokx: klopt. Ik wil de lagen zo bouwen dat ze ook op zichzelf kunnen staan (de presentatie + controle als 1 en de model- + abstractie- + databaselaag als 1), maar ik wil beide producten zelfstandig veilig hebben.

In ieder geval, optie 1 valt dus al af ;) Het lijkt me eigenlijk prima om voor de 2e optie te gaan: dan garandeer ik in elk gedeelte veiligheid, ook als ze los van elkaar gebruikt worden.

@mithras: hmm.. aan dubbele escaping en gaten had ik nog niet gedacht. Dat probleem krijg ik dus ook als ik in beide onderdelen (cms en database) ga escapen :/ Misschien dan toch maar voor de optie gaan waarin je de escaping ed alleen in de aller aller aller onderste laag stopt

[ Voor 25% gewijzigd door coenbijlsma op 04-08-2007 14:00 ]


Acties:
  • 0 Henk 'm!

  • Thralas
  • Registratie: December 2002
  • Laatst online: 24-08 21:46
eamelink schreef op zaterdag 04 augustus 2007 @ 13:51:
Hier maak je het verschil tussen een string en bijvoorbeeld een functie, die niet ge-escaped hoeft te worden :). Ik pak dan meestal gewoon een boolean $escape.
Ik zie niet in waarom je het op dat niveau zou willen regelen. Je kunt er in je ' database layer' gewoon vanuit gaan dat geen enkele variabele in een query te vertrouwen is.
Ook al schrijf je ooit een script dat de betreffende db-class gebruikt en slechts 'veilige' md5 hashes opslaat, je db class tracht ook die input te escapen.
mithras schreef op zaterdag 04 augustus 2007 @ 13:52:
[...]

Wat je nu dus doet is de presentatie bepalen in de database laag. Terwijl dat dus eigenlijk je fundamentele laag moet zijn die veel informatie terugkoppelt naar bovenliggende lagen. Als je als website-bouwer uiteindelijk bepaalt om op een forum de sql-injectie niet te tonen, moet dat kunnen. Als ik echter in een totaal andere webapplicatie bepaal dat het wél moet kunnen, zit je met de gebakken peren als je framework het niet meer ondersteund.

Het toch invoeren van de ge-escapede data ligt los van het feit dat je terugkoppeling wilt hebben. Bij voorkeur naar een aparte error-constructie (een laag of object, dat is je eigen keuze). Of je die fouten vervolgens uit dat object gaat gebruiken is hier niet aan de order :)
Waar wordt er presentatie bepaald in de DB layer? Je gaat ervanuit dat alles wat je aan je DB class voert opgeslagen wordt en er hetzelfde weer uitkomt. Dus als iemand mijn gastenboek probeert te exploiten en als body ';DELETE * FROM USERS-- post, dan wil ik dat later ook gewoon zien als entry als ik het gastenboek bekijk (je kunt het er altijd nog in je gastenboek-class eruitfilteren), niet dat m'n users tabel opeens weg is.
En wat als je nu een modulair systeem hebt waarbij verschillende mensen aan je framework werken. Gaat persoon 1 in laag a escapen, persoon 2 in laag b en je krijgt daardoor juist gaten of dubbele escaping ;)
Simpel; Net voordat je data in je database opslaat zorg je dat alles escaped is. Iemand die op een hoger niveau bezig is de data te escapen is fout bezig (let op, dit staat los van validatie). Je 'hogere' lagen kunnen data valideren (bv. lengte van een string), maar gaan er verder vanuit dat je databaseclass ervoor zorgt dat de input opgeslagen wordt, en niet als uitvoerbare opdracht wordt gezien.

[ Voor 4% gewijzigd door Thralas op 04-08-2007 14:17 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Injection: Alleen in onderste laag (bij jou databaselaag) lijkt me:
Want, de andere lagen kunnen niet 'weten' hoe er geescaped moet worden. Je zou je databaselaag bijvoorbeeld ooit kunnen veranderen naar een andere database, of een compleet andere data-bron. Als er dan in een van de bovenliggende lagen al geescaped word (database-specifiek), dan moet je al die lagen ook aanpassen. Lijkt me onwensbaar.

Aka: Je wil niet dat de presentatielaag en dergelijke weet hoe de interne delen van je datalaag werkt (waaronder dus ook de specifieke manier van escapen voor jou databasesysteem).

Dus: Databaselaag zou ik zo doen:
database connectie maken, queries, een raw escape functie, en eventueel een parametersysteem (zoals je bij PDO ook ziet, kan heel handig zijn).

Bovenliggende lagen moeten natuurlijk wel (voordat ze hun data doorvoeren naar de databaseclass) hun eigen checks doen op de data: Zoals validatie (juiste type data, juiste formaar, enz, enz).

[ Voor 10% gewijzigd door Verwijderd op 04-08-2007 14:27 ]


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Wat dacht je van - buiten je normale beveiliging! - in je database zelf? Heb je het ooit voor elkaar gekregen het SQL-commando DROP in een INTEGER te proppen? Heb je het ooit voor elkaar gekregen het commando DROP te gebruiken terwijl je MySQL user daar geen rechten voor had?

Ik weet dat heel veel mensen niet vaak met procedures en functions werken en meerdere gebruikers voor MySQL omdat hun hostingboeren vaak niet voorbereid zijn op zulke enorme technologische vraagstukken ('MySQL? Jazeker meneer, tegenwoordig versie 4 zelfs!'). Maar als je er nou eens gewoon van uit gaat dat je beveiliging niet goed genoeg is binnen PHP, ondanks alles wat je er aan gedaan hebt - wat een gezond paranoide instelling is IMHO - het toch mogelijk is om rotzooi richting MySQL te slingeren, dan bouw je daar toch ook nog een beveiligingslaag in?

Dus gebruik MySQL users met beperkte rechten, of gebruik er meerdere waar toepasbaar, dat er een aparte DB-user is voor CMS-gebruikers, en een aparte user voor gewone bezoekers, die natuurlijk nog weer minder moeten kunnen.

Verder timmer je met prepared statements ook weer een hoop dicht.

Gebruik functions en procedures om op SQL-niveau zaken makkelijker beheersbaar te houden.

Zorg dat je in PHP altijd al weet voordat je een prepared statement uitvoert wat voor een soort variabele je hebt (overeenkomstig met SQL), en of deze kosher is.

Zorg dat je in PHP geen enkele variabele in je code gaat gebruiken die ongecheckt is doordat je in je framework er voor zorgt dat je nooit zomaar $_POST['variabele'] gebruikt maar een nabewerking daarvan, $posted['variabele'] ofzo. Je weet op iedere pagina altijd precies welke $_GET, $_POST en $_FILE variabelen je verwacht, als je dus van te voren aangeeft wat voor variabele je verwacht onder welke naam, dan werkt dat prima.

[ Voor 13% gewijzigd door BikkelZ op 04-08-2007 14:34 ]

iOS developer


Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Thralas schreef op zaterdag 04 augustus 2007 @ 14:16:
Ik zie niet in waarom je het op dat niveau zou willen regelen. Je kunt er in je ' database layer' gewoon vanuit gaan dat geen enkele variabele in een query te vertrouwen is.
Je wilt natuurlijk wel de mogelijkheid behouden om MySQL functies te gebruiken ;)

Acties:
  • 0 Henk 'm!

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
@Bikkelz: daar heb je een punt mee. Alleen: het doel van het databasegedeelte van m'n framewerkje is ook dat ik geen queries meer hoef te typen, en dat ze automatisch gegenereerd worden. Nog niks mis met jou statement tot nu toe, maar ik wil ook dat er automatisch tabellen gegenereerd worden (etc..) zodra ik een php-class instantieer waarvan nog geen tabel bestaat (voor bijvoorbeeld installatie van het geheel). Dan moet de MySQL-user die rechten dus ook hebben.
Wat ik wel zou kunnen doen is gebruik maken van 2 verschillende users: 1 voor de installatie en 1 voor het gebruik. Dan gaat je verhaal wel op, en het bevalt me wel eigenlijk 8)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
De databaselaag in dit voorbeeld is (neem ik aan) bedoeld om de bovenliggende lagen hun data te laten opslaan/ophalen. Dan hoort die laag gewoon de escaping te doen. Als ik een tekst "blah');DROP TABLE forum;" wil opslaan dan wil ik ook die tekst opslaan en niet het commando uitvoeren (Drop table...). Als ik een table wil droppen dient de databaselaag daar een voorziening in te verschaffen, net zoals deze laag een voorziening verschaft op een class object op te slaan in de juiste tabellen. Dus naast een .SaveMessage method (om maar wat te noemen) dient de laag ook een .DropTable method aan te bieden dan.

Uiteraard dien je de beveiliging e.d. op table-niveau en executie rechten etc. in het RDBMS zelf te regelen, maar dat staat hier los van. Het commando "Drop table" in de tekst die ik hierboven noem moet gewoon nooit überhaupt de kans krijgen om uitgevoerd te worden, los van het feit of je er rechten voor hebt. Een .SaveMessage moet doen wat 't zegt: de message opslaan en niet (als 'side-effect') ook nog doodleuk de message als command interpreteren en dan doodleuk uitvoeren.

Als iemand je CMS gebruikt met een eigen/andere databaselaag dan dient die laag gewoon ook de escaping te doen. Simple as that.

Maar waarom zou je uberhaupt escapen en niet gewoon parametrized query's of zelfs stored procedures gebruiken?
eamelink schreef op zaterdag 04 augustus 2007 @ 14:36:
[...]
Je wilt natuurlijk wel de mogelijkheid behouden om MySQL functies te gebruiken ;)
Dan dien je die ook in je laag in te bouwen (of een generieke .ExecuteStatement(string Query) aan te bieden, maar die method roep je dus natuurlijk niet aan in je .SaveMessage).

[ Voor 60% gewijzigd door RobIII op 04-08-2007 15:25 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
Verhelderend!
RobIII schreef op zaterdag 04 augustus 2007 @ 15:18:
Maar waarom zou je uberhaupt escapen en niet gewoon parametrized query's of zelfs stored procedures gebruiken?
Dat ga ik bouwen als ik de generieke functionaliteit af heb. Ik weet dat het bad practice is, maar ik wil dit eerst werkend hebben voordat ik dat erin ga bouwen (ook om te leren hoe het precies werkt), en daarna lever ik wel een versie 1.1 op ofzo O-)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

RobIII schreef op zaterdag 04 augustus 2007 @ 15:18:
Maar waarom zou je uberhaupt escapen en niet gewoon parametrized query's of zelfs stored procedures gebruiken?
Stored procedures en prepared statements zijn niet de heilige performance graal als je heel diverse distributies van datapunten in je database hebt, daarnaast zijn dingen als IN-lijsten en queries die afhangen van de gekozen inputs er niet altijd erg praktisch in op te lossen, dus je kan ze niet altijd gebruiken.

Zelf lijkt het me het beste om twee dingen te doen om sql-injection te voorkomen en het staat ook al in andere reacties hier:
- Zorg dat je een variabele altijd "veilig" binnenhaalt. Dus als je een integer wilt hebben, zorg dan ook dat het een integer is. Dat moet je in de laag uitvoeren die de formdata binnenhaalt, want je wil natuurlijk niet overal in je applicatielagen moeten checken of iets echt wel een integer is, terwijl je dat met 1 check op kan lossen en intern uberhaupt niet hoeft te doen.

- Als je door bovenstaande weet dat je altijd het soort variabele krijgt wat je vraagt, dan kan je vervolgens vrij eenvoudig in de laag die met de database communiceert, danwel in de laag die de queries samenstelt ervoor zorgen dat je tekstvariabelen de goede escaping hebben.
Als je dat uiteindelijk oplost met parametrized queries, prepared statements en/of stored procedures (waar je afhankelijk van de manier van aanroepen/aanroepbaarheid *ook* moet escapen) is dan voor de bovenste lagen niet relevant. Voor die bovenste lagen zijn ', '' of \' drie verschillende strings die als het goed is geen bijzondere betekenis hebben :P

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

RobIII schreef op zaterdag 04 augustus 2007 @ 15:18:
Dan dien je die ook in je laag in te bouwen (of een generieke .ExecuteStatement(string Query) aan te bieden, maar die method roep je dus natuurlijk niet aan in je .SaveMessage).
Natuurlijk, maar vaak zit dat beide in een enkele query. Sla een bericht op met inhoud (moet ge-escaped worden) en een datum (niet ge-escapede functie NOW()), en je hebt het al. Daar maak je dus het verschil tussen een string die ge-escaped moet worden, en een stukje veilige inhoud die uitgevoerd mag worden. Vandaar dat ik zeg dat je het beste kan escapen op de plek waar je zowel een string als een functie ergens inmikt :)

[ Voor 77% gewijzigd door een moderator op 04-08-2007 18:12 . Reden: Woei... edit i.p.v. quote :X ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
eamelink schreef op zaterdag 04 augustus 2007 @ 17:31:
[...]
Natuurlijk, maar vaak zit dat beide in een enkele query. Sla een bericht op met inhoud (moet ge-escaped worden) en een datum (niet ge-escapede functie NOW()), en je hebt het al. Daar maak je dus het verschil tussen een string die ge-escaped moet worden, en een stukje veilige inhoud die uitgevoerd mag worden.
Als het goed is weet je .SaveMessage method dan welke parameters ge-escaped moeten worden (en nog liever de databaselaag zélf) en zou je dus als devver die 'het framework' gebruikt je daar geen zorgen over moeten maken. In jouw voorbeeld zou de .SaveMessage method niet eens een "now" parameter hebben want die is 'hardcoded' in je query. En als je een datum parameter had gemaakt had je die al afgedwongen op het juiste type (datetime) door de parameter van de .SaveMessage method van het datetime type te maken en daar kan dus ook niets mis mee (note: strong-typed dan). Enkel strings ((n)varchar/text/etc.) moet je dan nog escapen.
eamelink schreef op zaterdag 04 augustus 2007 @ 17:31:
[...]
Vandaar dat ik zeg dat je het beste kan escapen op de plek waar je zowel een string als een functie ergens inmikt :)
En ik zeg dus dat als ik "bovenop" de databaselaag ga zitten devven ik weinig zin heb om die laag bij iedere scheet te moeten vertellen of 'ie de parameter moet escapen. Als ik het 1 keer vergeet ergens ga je al de mist in. Dat hoort die laag zelf te weten danwel uit te zoeken.
ACM schreef op zaterdag 04 augustus 2007 @ 17:13:
Stored procedures en prepared statements zijn niet de heilige performance graal als je heel diverse distributies van datapunten in je database hebt
Daar heb ik het dan ook niet over gehad ;)
ACM schreef op zaterdag 04 augustus 2007 @ 17:13:
daarnaast zijn dingen als IN-lijsten en queries die afhangen van de gekozen inputs er niet altijd erg praktisch in op te lossen, dus je kan ze niet altijd gebruiken.
Niet altijd nee, maar vaak wel ;)
ACM schreef op zaterdag 04 augustus 2007 @ 17:13:
Zelf lijkt het me het beste om twee dingen te doen om sql-injection te voorkomen en het staat ook al in andere reacties hier:
- Zorg dat je een variabele altijd "veilig" binnenhaalt. Dus als je een integer wilt hebben, zorg dan ook dat het een integer is.
Dat vind ik het voordeel van strong-typed platformen ;) Maar inderdaad; bij het ophalen van post/get spul meteen casten naar de juiste typen (evt. een error throwen als dat niet lukt) en daar mee verder werken/rekenen. Scheelt je ook nog eens door al je lagen heen op-en-neer casten.
ACM schreef op zaterdag 04 augustus 2007 @ 17:13:
Als je dat uiteindelijk oplost met parametrized queries, prepared statements en/of stored procedures (waar je afhankelijk van de manier van aanroepen/aanroepbaarheid *ook* moet escapen) is dan voor de bovenste lagen niet relevant.
My point exactly. Wat voor nut hebben die lagen dan anders? :P

[ Voor 38% gewijzigd door RobIII op 04-08-2007 18:18 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

RobIII schreef op zaterdag 04 augustus 2007 @ 18:11:
Daar heb ik het dan ook niet over gehad ;)
De reden dat ik het noem is om duidelijk te maken dat je niet elke query kan vervangen door een parametrized/prepared/stored statement. En dat dat dus niet altijd enkel om syntactische redenen niet altijd kan ;)
Niet altijd nee, maar vaak wel ;)
Als ik moet schatten hoeveel queries wij met een min-of-meer dynamische IN-lijst doen, denk ik dat we op de frontpage al gauw richting of zelfs voorbij de 10% gaan... Het aantal queries dat dynamisch wordt opgebouwd is wat lager, dat zal rond de 1% zitten. Maar voor die 11% moet dan dus alsnog functionaliteit bestaan om ook daar veilig mee te kunnen werken.
Dat vind ik het voordeel van strong-typed platformen ;) Maar inderdaad; bij het ophalen van post/get spul meteen casten naar de juiste typen (evt. een error throwen als dat niet lukt) en daar mee verder werken/rekenen. Scheelt je ook nog eens door al je lagen heen op-en-neer casten.
Castings-performance merk je nauwelijks iets van in php en soms werkt expliciet casten juist nadelig of is het eigenlijk nergens voor nodig (bijv omdat je het getal toch alleen maar in strings gebruikt), maar zeker weten dat iets van een bepaald type is - of een geldige alternatieve (string)representatie ervan - is wel noodzakelijk :)

Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

coenbijlsma schreef op zaterdag 04 augustus 2007 @ 14:37:
@Bikkelz: daar heb je een punt mee. Alleen: het doel van het databasegedeelte van m'n framewerkje is ook dat ik geen queries meer hoef te typen, en dat ze automatisch gegenereerd worden. Nog niks mis met jou statement tot nu toe, maar ik wil ook dat er automatisch tabellen gegenereerd worden (etc..) zodra ik een php-class instantieer waarvan nog geen tabel bestaat (voor bijvoorbeeld installatie van het geheel). Dan moet de MySQL-user die rechten dus ook hebben.
Wat ik wel zou kunnen doen is gebruik maken van 2 verschillende users: 1 voor de installatie en 1 voor het gebruik. Dan gaat je verhaal wel op, en het bevalt me wel eigenlijk 8)
Zie:

http://dev.mysql.com/tech...ysql-storedprocedures.pdf

Pagina 42, SQL SECURITY DEFINER.

Je geeft dan eigenlijk iemand rechten om onder root (of wat je wil) een bepaalde stored procedure uit te voeren.

iOS developer

Pagina: 1