Computerbeveiliging - Hoe je bad guys buiten de deur houdt

SQL injectie in index

26-07-2012, 16:52 door Anoniem, 36 reacties
Hallo

mijn site (index.php) is te hacken met sql injectie.

hoe kan ik mijn index zo aanpassen dat hij niet meer lek is?

Hartelijk dank
Reacties (36)
26-07-2012, 17:27 door DanielG
niet.
26-07-2012, 17:27 door Anoniem
https://www.owasp.org/index.php/SQL_Injection

Succes
26-07-2012, 17:42 door SirDice
Door de foute code te herschrijven en te zorgen dat het niet meer mogelijk is.

En zonder zicht op de code kunnen wij alleen maar gokken waar de fout zit.
26-07-2012, 18:04 door Anoniem
Middels een invoer veld? (bijvoorbeeld een zoekfunctie)

Om dat te voorkomen is naar mijn weten het makkelijkste door 'regels' op te leggen bij het betreffende invul veld.
Bijvoorbeeld dat enkel de characters a-z,A-Z,0-9. Dus dat er alleen gezocht kan worden zonder tekens.

Voorbeeldje in PHP:

if (! ereg('[A-Za-z0-9]', $zoekfunctie))
{
die("Hier de HTML foutmelding hier als er een ongeoorloofd character wordt gebruikt");
}

Verder schijnt het ook mogelijk te zijn middels een aanpassing in de URL.
ben even de correcte benaming kwijt, maar dat is ook sql injection.

Misschien dat iemand anders dat kan aanvullen. :)
26-07-2012, 23:14 door Preddie
Dat is natuurlijk helemaal afhankelijk van de vorm van SQL injectie die mogelijk is.
Een belangrijke regel bij het programmeren is dat je de gebruikersinput valideert (input-, verwerking- en ouputvalidatie) dat komt er op neer dat je alleen accepteert wat je wilt verwerken. In dit geval zou dat bijv. neer komen het filteren van quotes en andere tekens.

Zoals Sirdice al aangeeft kunnen we je daar alleen bij helpen als we zicht hebben op de code. je zou de code of het kwetsbare deel daarvan hier kunnen posten. Zonder de code is het erg moeilijk een concrete oplossing voor jou probleem te geven
27-07-2012, 00:13 door Anoniem
Escape elke string die je in je mySQL query stopt met mysql_real_escape_string(), en haal cijfers door intval / floatval.
27-07-2012, 00:43 door Anoniem
Google is qua programmeren een vriend.
Zoekterm: "Hack-proofing Your PHP SQL"
https://www.google.nl/search?hl=nl&q=Hack-proofing+Your+PHP+SQL
Succes!
27-07-2012, 11:36 door Preddie
Zoals anoniem net voor mij aan geeft kun je gebruik maken van regular expressions om de invoer te valdieren of te filteren. Echter zijn er ook standaard functies die je helpen te voorkomen dat er verschillende vormen van SQL injectie uitgevoerd kunnen worden zoals bijv. de mysql_real_escape_string()
27-07-2012, 11:51 door Anoniem
@"18:04 door Anoniem":
Dit is een slechte oplossing, wat nu als iemand een bericht zoals dit wilt plaatsen met '' dat is dan ook verboden.
En ereg() is deprecated en zelf helemaal verwijderd in php5.4.

Als je wilt controleren of iets een nummer is of tekst kan je beter gebruiken maken.
http://nl3.php.net/ctype

Zoals Predjuh al aangeeft moet je gebruik maken van de juiste escape functies.
Er is overigens niks mee om ook getallen door een escape functie te halen, de database heeft hier geen problemen mee en als het getal ongeldig is krijg je een foutmelding. En vergeet niet dat SQL invoer inclusief met gebruik van escaping tussen ' ' moet staan, anders ben je alsnog kwetsbaar, uitzondering is een getal die je door intval() hebt gehaald.

Als laatste waarschuwing, addslashes() is GEEN OPLOSSING!! Nu niet nooit niet!
http://www.slideshare.net/billkarwin/sql-injection-myths-and-fallacies

En vergeet ook niet magic_quotes uit te zetten, anders word je invoer compleet verminkt.
27-07-2012, 12:06 door Anoniem
Never trust user input!
27-07-2012, 12:13 door Anoniem
Dude, gewoon mysql_real_escape_string()

Done.
27-07-2012, 13:05 door Security Scene Team
Door SirDice: Door de foute code te herschrijven en te zorgen dat het niet meer mogelijk is.

En zonder zicht op de code kunnen wij alleen maar gokken waar de fout zit.

Juist, kijk welk stukje code dit probleem veroorzaakt. anders even jouw bevindingen hier posten en de code waar het omgaat.

verder kun je CTracker installeren, een soort van php firewall welke niet meer in ontwikkeling is (wat ik heb begrepen)
maar wel erg goed werkt. het is opensource dus ben je een beetje goed met php dan kun je hiermee zeker uit de voeten.

mocht je hem niet als download meer kunnen vinden, laat het dan ff weten dan upload ik ff een kopietje voorje.

Mvg

SSTeam.
27-07-2012, 13:43 door Anoniem
In het kader van anoniem (12:06);

hardcoded database communicatie, database onbereikbaar vanaf internet.

encryptie van database content, decryptie op basis van valide user input (rest is invalide). server side hardcoded encryptie (vrij natuurlijk), sleutels relateren aan user locatie op jou cms platform. zoiets werkt ook goed.
27-07-2012, 16:46 door [Account Verwijderd]
[Verwijderd]
27-07-2012, 21:39 door WhizzMan
Beste anoniem. Als je niet je broncode laat zien, kan niemand concreet wat zeggen. Er worden allerlei tools genoemd, waarvan sommige zelfs een beetje werken, maar de praktijk is dat je je code moet laten auditen door iemand die weet hoe dat moet. Filters en Web Application Firewalls en dergelijke zijn lapmiddelen die vaak maar gedeeltelijk werken.

Als je dan toch een generalistisch advies zou moeten geven: gebruik prepared statements en valideer je input. Doordat je prepared statements gebruikt, zal geinjecteerde code niet worden uitgevoerd. Inputvalidatie (in je phpscript, niet met javascript in de browser, dat is te omzeilen) zal foutmeldingen moeten genereren als de input niet voldoet aan wat je wilt. Dat doe je inderdaad met een filter, maar dat filter zit er niet om injectie tegen te gaan, maar om foute input te vermijden, zodat je script goed werkt. Als je op deze manier je webscripts opbouwt, heb je veel minder kans op kwetsbaarheden.
28-07-2012, 04:04 door [Account Verwijderd]
[Verwijderd]
28-07-2012, 08:58 door Anoniem
Als je niet begrijpt wat SQL injection is, en dus ook niet goed begrijpt hoe SQL door de database wordt gebruikt, kun je het probleem ook niet oplossen: Je ziet je eigen fouten niet.

Zomaar roepen dat het gebruik van mysql_real_escape_string() voldoende is, laat al zien dat deze man/vrouw niet snapt hoe het werkt en zeer waarschijnlijk nog steeds lekke code oplevert. Dit geldt ook voor het gebruik van een regex voor input validatie, ook dat is niet bestand tegen SQL injection.

Laat de database bepalen welke parameters er benodigd zijn om de query uit te voeren en laat de database ook de juiste datatypes voor deze parameters bepalen. Wanneer het id een integer is en je hebt deze voorwaarde WHERE id = ? is er sprake van één parameter van het type integer. Alle andere mogelijke input moet een foutmelding opleveren. Het gebruik van prepared statements doet wonderen.

Mits je niet al een geïnjecteerd stuk SQL gaat prepareren, ook dat is gewoon een fout van de programmeur. Userinput mag alleen als parameter worden ingegeven.
28-07-2012, 10:48 door Anoniem
Door Hugo: Download deze PHP SQL drivers http://www.banshee-php.org/files/database.tar.gz en gebruik deze op de volgende manier: http://www.banshee-php.org/documentation/libraries/database

De belangrijkste functies zijn query() en execute(). De eerste parameter is de printf-achtige query string, zonder de gebruikersinvoer. Deze gebruikersinvoer zijn de parameters die daarna komen. Houd je aan deze eenvoudige syntax en SQL injections zijn verleden tijd.

Leuk, maar er staan toch een paar punten van kritiek in.
* Magic methods zijn langzaaaaam. Soms zelfs een factor 30 langzamer dan gewone functies. Helemaal als je dan ook nog is call_user_func() gaat gebruiken terwijl je functies gewoon beschikbaar kunnen zijn.
Aangezien er gebruik word gemaakt van PHP5 is het veel beter gebruik te maken van een interface of abstract methods ipv er vanuit te gaan dat de functie bestaat.

[/quote] public function last_insert_id($history = null) {
if ($history !== null) {
$size = count($this->insert_id_history);
return $history < $size ? $this->insert_id_history[(int)$history] : 0;
} else if ($this->db_insert_id == null) {
return false;
} else if (($last_id = call_user_func($this->db_insert_id, $this->link)) == 0) {
return $this->last_insert_id(0);
} else {
return $last_id;
}
}[/quote]
Is dit een grap? Je roep een functie aan om te kijken of het 0 is en roept dan vervolgens ZICH ZELF aan met 0 zodat hij 0 teruggeeft! WTF?!?!?! DIT IS TE DOM VOOR WOORDEN!

"print $format."\nQuery not accepted.\n";"
Zeker nooit gehoord van excepties en normale fouthandeling.

"if (in_array($statement, array("select", "show")) == false) {"
Hiermee worden statements als EXECUTE, START TRANSACTION, WITH (Common Table Expression) uitgesloten en PostgreSQL ondersteund meerdere statements achter elkaar (oeps!).

"print "Dropped query that tried to change the database via a read-only database connection.\n";"
Nogmaals excepties en foutafhandeling, dit is goud voor een hacker! Hij weet nu dat ZIJN query dus niet mag maar wel word doorgelaten.

Wat dat betreft doet het ze naam dan eer aan.
"In legend, a banshee is a fairy woman who begins to wail if someone is about to die."
28-07-2012, 11:47 door [Account Verwijderd]
[Verwijderd]
28-07-2012, 13:08 door Anoniem
Gebruik mysql_real_escape_string om SQL injection te voorkomen, als je niet weet waar het lek zit doe je een foreach over $_POST of $_GET en doe je daarover een escape, dan weet je zeker dat je veilig zit (alhoewel dit niet de meest nette manier is).
28-07-2012, 14:02 door Anoniem
Door Hugo: PDO is veel te omslachtig. En daarbij kan je met PDO geen tabel- of kolomnamen via prepare() laten invullen.

Dat komt omdat de onderliggende drivers dit niet ondersteunen, en dit ook niet het doel van een prepared statement is.
Een prepared statement is om bedoeld om meerdere malen te worden uitgevoerd met verschillende waardes, met name INSERT profiteert hiervan.

Voor een query die slechts één keer word uitgevoerd is prepare() veelte zwaar dat moet ik je nageven.
Daarom wordt PDO ook vaak bekritiseerd, PostgreSQL ondersteund pg_query_params() waarmee je op een vergelijkbare manier als prepared statement kan werken. MySQL heeft dit ook, maar iemand heeft daar flink liggen slapen want de parameters werken alleen met '?' dus je weet pas of niet klopt als het goed fout gaat.
29-07-2012, 01:03 door [Account Verwijderd]
[Verwijderd]
29-07-2012, 01:13 door [Account Verwijderd]
[Verwijderd]
29-07-2012, 12:29 door Anoniem
Door Hugo: PDO is veel te omslachtig. En daarbij kan je met PDO geen tabel- of kolomnamen via prepare() laten invullen.
Wanneer PDO dit wél zou kunnen, is het weer zo lek als een mandje... Je weet blijkbaar niet wat een prepared statement is, anders zou je niet eens poging doen om een variabele tabel- of kolomnaam op te geven.

Met PostgreSQL en PHP kun je met pg_query_params(), het gebruik van stored procedures en quote_ident() (functie in PostgreSQL) SQL injection volledig tegengaan, ook met variabele tabel- en kolomnamen. In je PHP-code roep je uitsluitend stored procedures aan en binnen deze procedures schrijf je de SQL die moet worden uitgevoerd. Met quote_ident() en quote_literal() maak je iedere vorm van SQL-injection onschadelijk. Uiteraard ga je ook de juiste rechten toekennen aan de verschillende database rollen: Niemand mag direct de tabellen benaderen, alleen de eigenaar van de tabellen. En deze gebruik je NOOIT EN TE NIMMER als rol vanuit jouw (PHP-) applicatie. De applicatie mag uitsluitend de stored procedures aanroepen, de SQL aanroepen waarvan jij weet dat deze veilig is. En mocht je toch nog ergens een lek hebben, dan is dit vrij snel gevonden: Alle SQL bevindt zich op één plek, centraal in de database.

Omschakelen naar een andere programmeertaal, bv. .NET of Java, is dan ook eenvoudig, gewoon de bestaande stored procedures aanroepen.

Ps. Met Oracle en SQL Server kun je hetzelfde doen, met MySQL werkt dit echter niet.
29-07-2012, 12:30 door Anoniem
Door Hugo:
Door Anoniem: Gebruik mysql_real_escape_string om SQL injection te voorkomen, als je niet weet waar het lek zit doe je een foreach over $_POST of $_GET en doe je daarover een escape, dan weet je zeker dat je veilig zit (alhoewel dit niet de meest nette manier is).
Zoals eerder al gezegd is dit niet waar.
Hoezo is dit niet waar? Als je eerst een database verbinding maakt en dan de arrays post en get uitleest en deze vervolgens onschadelijk maakt dmv mysql real escape string zit je gewoon veilig.
29-07-2012, 16:11 door [Account Verwijderd]
[Verwijderd]
29-07-2012, 16:38 door Anoniem
Door Bergen:
Door Anoniem:
Voor een query die slechts één keer word uitgevoerd is prepare() veelte zwaar dat moet ik je nageven.
Ja, dit is een goed punt om te benadrukken, al hangt "veel te zwaar" af van de website.

Prepare is inderdaad trager, in de orde van milliseconden per query (ook afhankelijk van de moeilijkheid van de query natuurlijk).
Is dat wel zo? Is dit wel meetbaar? De database moet het queryplan altijd eerst opstellen en dan uitvoeren. Met een gewone query doe je deze twee stappen samen, met een prepared statement doe je dit in twee aparte stappen. Het verschil zit hem in de netwerk overhead, wat zéér minimaal kan zijn. En een prepared statement is herbruikbaar, ook X tijd later nog.

Bij een erg grote en drukke website met ontzettend veel SQL-verkeer zou je daar vast last van krijgen. De Tweakers.net servers moeten bijvoorbeeld honderden tot wel duizend queries per seconde verwerken, dan is elke milliseconde winst van harte welkom:

http://tweakers.net/stats/?Action=Serverstats&Mode=MySQL

Bij een website met maar een paar duizend pageviews per dag heeft dit geen merkbare performance impact, want dan zitten er gemiddeld meerdere seconden tussen elke pageview. De database server wordt dus praktisch niet belast. Bescherming tegen SQL-injectie is natuurlijk veel belangrijker dan een ietsjepietsje tragere pageviews, dus op zo'n website zou ik altijd prepared statements gebruiken.
Dit juist een plek om prepared statements te gebruiken! 95% van de queries, als het niet meer is, zijn namelijk exact hetzelfde, alleen de parameters verschillen. Bij webapplicaties, waarin de SQL toch al hardcoded in staat (al dan niet in een framework of ORM), is het sterk aan te raden om prepared statements te gebruiken, de website wordt sneller én je bent beschermd tegen SQL injection. Of laat je jouw bezoekers hun eigen unieke queries schrijven? Het lijkt me sterk.
30-07-2012, 00:28 door [Account Verwijderd]
[Verwijderd]
30-07-2012, 08:16 door regenpijp
Door Hugo:
Door Anoniem:
Hoezo is dit niet waar? Als je eerst een database verbinding maakt en dan de arrays post en get uitleest en deze vervolgens onschadelijk maakt dmv mysql real escape string zit je gewoon veilig.

$id = mysql_real_escape_string($_GET["id"]);
$query = "select column from some_table where id=".$id;

als ik nu als id in de URL de volgende waarde neem: "0 union select password from users where id=1".
mysql_real_escape_string() verandert niks aan de id parameter en toch heb je een knaller van een SQL injection.

mysql_real_escape_string beschermt niet tegen SQL injectie in integers, laatst nog getest en dit werkt ook:
$id = mysql_real_escape_string($_GET["id"]);
$query = "select column from some_table where id='$id'";
Misschien zal je wel wat in je tabel moeten veranderen, maar ik heb iedere waarde toch standaard op TEXT staan, is wat makkelijker in gebruik en ook wat minder efficient, weet ik. :)
30-07-2012, 11:08 door Anoniem
Door Anoniem:
Door Hugo: PDO is veel te omslachtig. En daarbij kan je met PDO geen tabel- of kolomnamen via prepare() laten invullen.
Wanneer PDO dit wél zou kunnen, is het weer zo lek als een mandje... Je weet blijkbaar niet wat een prepared statement is, anders zou je niet eens poging doen om een variabele tabel- of kolomnaam op te geven.

Met PostgreSQL en PHP kun je met pg_query_params(), het gebruik van stored procedures en quote_ident() (functie in PostgreSQL) SQL injection volledig tegengaan, ook met variabele tabel- en kolomnamen. In je PHP-code roep je uitsluitend stored procedures aan en binnen deze procedures schrijf je de SQL die moet worden uitgevoerd. Met quote_ident() en quote_literal() maak je iedere vorm van SQL-injection onschadelijk. Uiteraard ga je ook de juiste rechten toekennen aan de verschillende database rollen: Niemand mag direct de tabellen benaderen, alleen de eigenaar van de tabellen. En deze gebruik je NOOIT EN TE NIMMER als rol vanuit jouw (PHP-) applicatie. De applicatie mag uitsluitend de stored procedures aanroepen, de SQL aanroepen waarvan jij weet dat deze veilig is. En mocht je toch nog ergens een lek hebben, dan is dit vrij snel gevonden: Alle SQL bevindt zich op één plek, centraal in de database.

Omschakelen naar een andere programmeertaal, bv. .NET of Java, is dan ook eenvoudig, gewoon de bestaande stored procedures aanroepen.

Ps. Met Oracle en SQL Server kun je hetzelfde doen, met MySQL werkt dit echter niet.
Bijna goed :) je bent in de war met prepared statement en een STORED statement ook wel userdefined functions of stored function genoemd.

Een prepared statement is een statement dat is voorbereid om te worden uitgevoerd, bijvoorbeeld een INSERT met verschillende waardes. De invoer is gecontroleerd op syntax, parameters weten welke invoer ze mogen accepteren, table DDL locked etc. Voor een SELECT die je één keer uitvoert is het overkill in de zin dat je meer doet dan nodig. Zwaar was misschien niet het juiste word.

Stored statements laten (lieten?) echter in MySQL (vooral versies voor 6.0) zwaar te wensen over.
Zo werden stored functions niet meegenomen in de dumps (nee dit is geen grap) waardoor je bij een restore voor vervelende verassing kwam te staan. Voor zover ik weet zijn deze problemen grotendeels opgelost maar wel iets om op te letten.
30-07-2012, 13:23 door Anoniem
Door Anoniem:
Door Anoniem:

Bijna goed :) je bent in de war met prepared statement en een STORED statement ook wel userdefined functions of stored function genoemd.

Een prepared statement is een statement dat is voorbereid om te worden uitgevoerd, bijvoorbeeld een INSERT met verschillende waardes. De invoer is gecontroleerd op syntax, parameters weten welke invoer ze mogen accepteren, table DDL locked etc. Voor een SELECT die je één keer uitvoert is het overkill in de zin dat je meer doet dan nodig. Zwaar was misschien niet het juiste word.

Stored statements laten (lieten?) echter in MySQL (vooral versies voor 6.0) zwaar te wensen over.
Zo werden stored functions niet meegenomen in de dumps (nee dit is geen grap) waardoor je bij een restore voor vervelende verassing kwam te staan. Voor zover ik weet zijn deze problemen grotendeels opgelost maar wel iets om op te letten.[/quote]Ik ben helemaal niet in de war, het is mijn dagelijkse werk als database programmeur om met prepared statements en stored procedures te werken.

Iedere query die je op de database afvuurt, wordt door de database omgezet in een queryplan. Het opstellen van een queryplan is precies wat een prepared statement doet. Het uitvoeren van de query, dat is wat de execute doet. Met een "normale" query doe je beide acties in één keer, met een prepared statement doe je dit in twee aparte stappen. De prepare hoef je slechts 1x te doen, de execute kun je oneindig vaak herhalen zolang het prepared statement blijft bestaan op jouw database connectie. Dit is dus perfect voor webapplicaties, verschillende bezoekers vragen dezelfde data op en kunnen dus dezelfde queryplannen gebruiken. Goed voor performance (er hoeft geen queryplan meer te worden opgesteld) en veiligheid (geen SQL injection mogelijk).

Prepared statements en stored procedures zijn prima te combineren, het aanroepen van een stored procedure kan namelijk in een prepared statement.

MySQL versie 6 bestaat helemaal niet, dat is tot op heden een mislukt project. De meest recente GA versie, is versie 5.5, aan versie 5.6 wordt nog gesleuteld. Hou ook in de gaten dat MySQL niet de norm is bij databases, MySQL loopt functioneel jaren achter op de "gemiddelde" database. Dit is ook de reden waarom vele webprogrammeurs nog nooit van prepared statements hebben gehoord, MySQL kwam hier heel erg laat mee en is nog steeds beperkt in de mogelijkheden.
30-07-2012, 15:53 door Anoniem
deze post is vast gestart door de web 'developer' van accord.nl

1+1 = ?
31-07-2012, 11:03 door Anoniem
Door Anoniem:
Door Anoniem:
Door Anoniem:

Bijna goed :) je bent in de war met prepared statement en een STORED statement ook wel userdefined functions of stored function genoemd.

Een prepared statement is een statement dat is voorbereid om te worden uitgevoerd, bijvoorbeeld een INSERT met verschillende waardes. De invoer is gecontroleerd op syntax, parameters weten welke invoer ze mogen accepteren, table DDL locked etc. Voor een SELECT die je één keer uitvoert is het overkill in de zin dat je meer doet dan nodig. Zwaar was misschien niet het juiste word.

Stored statements laten (lieten?) echter in MySQL (vooral versies voor 6.0) zwaar te wensen over.
Zo werden stored functions niet meegenomen in de dumps (nee dit is geen grap) waardoor je bij een restore voor vervelende verassing kwam te staan. Voor zover ik weet zijn deze problemen grotendeels opgelost maar wel iets om op te letten.[/quote]Ik ben helemaal niet in de war, het is mijn dagelijkse werk als database programmeur om met prepared statements en stored procedures te werken.

Iedere query die je op de database afvuurt, wordt door de database omgezet in een queryplan. Het opstellen van een queryplan is precies wat een prepared statement doet. Het uitvoeren van de query, dat is wat de execute doet. Met een "normale" query doe je beide acties in één keer, met een prepared statement doe je dit in twee aparte stappen. De prepare hoef je slechts 1x te doen, de execute kun je oneindig vaak herhalen zolang het prepared statement blijft bestaan op jouw database connectie. Dit is dus perfect voor webapplicaties, verschillende bezoekers vragen dezelfde data op en kunnen dus dezelfde queryplannen gebruiken. Goed voor performance (er hoeft geen queryplan meer te worden opgesteld) en veiligheid (geen SQL injection mogelijk).

Prepared statements en stored procedures zijn prima te combineren, het aanroepen van een stored procedure kan namelijk in een prepared statement.

MySQL versie 6 bestaat helemaal niet, dat is tot op heden een mislukt project. De meest recente GA versie, is versie 5.5, aan versie 5.6 wordt nog gesleuteld. Hou ook in de gaten dat MySQL niet de norm is bij databases, MySQL loopt functioneel jaren achter op de "gemiddelde" database. Dit is ook de reden waarom vele webprogrammeurs nog nooit van prepared statements hebben gehoord, MySQL kwam hier heel erg laat mee en is nog steeds beperkt in de mogelijkheden.[/quote]
Excuus, ik had het helemaal verkeerd gelezen! Ik haalde twee reacties door elkaar.
"Hou ook in de gaten dat MySQL niet de norm is bij databases, MySQL loopt functioneel jaren achter op de "gemiddelde" database." Say no more ;)
01-08-2012, 19:26 door [Account Verwijderd]
[Verwijderd]
08-08-2012, 13:22 door Anoniem
Door Bergen: Ik heb het zelf niet gemeten, maar las op een andere website dat een beetje prepared statement zo 10 msec kon duren, voor de eerste run dan.
1) Je hebt het zelf niet gemeten voor jouw eigen unieke situatie, dus hoe wil je hier dan iets over roepen?
2) Die 10ms krijg je één keer voor je kiezen, bij het opstarten van jouw applicatie. En vervolgens kun je hier uren, dagen of zelfs maanden gebruik van blijven maken. Dan maken die eenmalige 10ms toch niet meer uit?
3) Op onze database server (PostgreSQL 9.1) voeren we tientallen queries in één transactie uit in gemiddeld 5 milliseconden per transactie op een database van ongeveer 5TB. En dat met een honderdtal concurrent bezoekers. Het totaal aantal transacties per seconde zweeft tussen de 1500 en 5000 stuks per seconde, afhankelijk van het aantal concurrent users en wat ze op dat moment uitvoeren. En iedere transactie bestaat dus uit ongeveer 30 verschillende queries.

Prepared statements zijn juist gemaakt om de performance te verbeteren, maak er dan ook gebruik van. Dat het ook een middel is om de beveiliging te verbeteren, dat is mooi meegenomen maar was nooit het doel van prepared statements. Wij hebben heel veel werk gestoken in het optimaliseren van de performance. Zonder prepared statements zouden wij nooit en te nimmer met de huidige hardware bovenstaande performance kunnen behalen, wordt direct heel veel langzamer.
08-08-2012, 13:54 door SirDice
Door regenpijp:
Door Hugo:
Door Anoniem:
Hoezo is dit niet waar? Als je eerst een database verbinding maakt en dan de arrays post en get uitleest en deze vervolgens onschadelijk maakt dmv mysql real escape string zit je gewoon veilig.

$id = mysql_real_escape_string($_GET["id"]);
$query = "select column from some_table where id=".$id;

als ik nu als id in de URL de volgende waarde neem: "0 union select password from users where id=1".
mysql_real_escape_string() verandert niks aan de id parameter en toch heb je een knaller van een SQL injection.

mysql_real_escape_string beschermt niet tegen SQL injectie in integers, laatst nog getest en dit werkt ook:
$id = mysql_real_escape_string($_GET["id"]);
$query = "select column from some_table where id='$id'";
Misschien zal je wel wat in je tabel moeten veranderen, maar ik heb iedere waarde toch standaard op TEXT staan, is wat makkelijker in gebruik en ook wat minder efficient, weet ik. :)
Om hier even op terug te komen...

$id = mysql_real_escape_string($_GET["id"]);
$query = "select column from some_table where id=".$id;
Is inderdaad vatbaar voor SQL injectie. Dit echter niet:

$id = mysql_real_escape_string($_GET["id"]);
$query = "select column from some_table where id='".$id."'";
Let vooral op de toevoeging van de quotes.

Puur het gebruik van mysql_real_escape_string() voorkomt geen SQL injectie, correct gebruik van mysql_real_escape_string() wel.

V.w.b. integer waardes kun je het beste intval() gebruiken.
Reageren

Deze posting is gelocked. Reageren is niet meer mogelijk.