De oplossing tegen SQL en XSS injecties is niet het gebruik van prepared statements of stored procedures, maar gewoon een erg simpel ALLE VREEMDE INVOER CONTOLEREN.
Dat is echt zo pertinent onjuist dat het niet grappig is
Het probleem is er niet een van ongecontroleerde invoer, het probleem is er een van data die over taaldomeinen heengaat. Het begint als POST data (dus bv UTF-8 tekst), en wordt bijvoorbeeld ge-embed in een SQL query en daarna in een HTML pagina, en op beide punten kan die data problemen opleveren door (al dan niet expres) als deel van die taal geinterpreteerd te worden.
Als je je 'input wil controleren', dan moet je bij invoer dus voor alle mogelijke taaldomeinen waar de data zou kunnen belanden (in bovenstaand voorbeeld dus SQL en HTML) nagaan of de input problemen op kan leveren. Als je daar nog een taaldomein aan toevoegt (bijvoorbeeld door later de data ook in Javascript of CSS te embedden), dan moet je bij de invoer dus ook nog controle daarvoor toevoegen. En je databases nalopen met die controle voor data die eerder is ingevoerd. Dat soort praktijken schalen niet en zijn foutgevoelig.
Invoer controleren is sowieso foutgevoelig, en de meningen over wat wel en niet kan verschillen. Denk bijvoorbeeld aan verschillende SQL servers die verschillende opties voor string literals of commentaar ondersteunen. Als je dan naar een andere SQL server overstapt zit je dan met je subtiel anders gecontroleerde data.
Nee, de juist aanpak is om alle invoer als onvertrouwd aan te merken, en bij gebruik van de data de data zo veilig mogelijk te embedden. Dat kan bij SQL queries bijvoorbeeld door parametrized queries te gebruiken; de invoer wordt dan simpelweg nooit als SQL geparsed en kan dus daar nooit een probleem opleveren.
Embedden in HTML kan veilig door de juiste karakters - zoals natuurlijk < - te escapen. (escapen is voor SQL natuurlijk ook mogelijk maar lastiger en dus gevaarlijker, en bovendien overbodig vanwege parametrized queries).
Prepared statements and stored procedures zijn alleen populair omdat het eenvoudige en luie manier is om vrijwel alle sql injections te voorkomen.
Ik ga er van uit dat je parametrized queries bedoelt, want dat is natuurlijk waar het om draait bij SQL injection.
En nee. Parametrized queries zijn
de manier om SQL-injectie 100% onmogelijk te maken. Door parametrized queries te gebruiken wordt je invoer
nooit als SQL beschouwd (maar als precies dat: invoer), en vermijd je dus alle risico's die daarmee gepaard gaan.
Echter ben je dan wel 100% afhankelijk van het feit dat er geen bug in de argument parser zit.
Dat is wel het slechtste argument dat ik ooit gehoord heb. Je bent ook 100% afhankelijk van het feit dat er geen bug in alle andere software die je gebruikt zit. Je bent afhankelijk van bugs in MySQL, Apache, Joomla en PHP bijvoorbeeld. Nogal wiedes.
Ook voorkomt het geen onjuiste invoer. In een naam zit gewoon geen cijfer en al helemaal geen procent tekens.
Dat is waar, maar dat is een ander probleem. Overigens zijn cijfers en procenttekens niet zo'n groot probleem voor SQL queries, maar een enkel aanhalingsteken des te meer. En laat dat nou toevallig wel een geldig teken voor in een naam zijn (denk aan namen als O'Reilly).
Het voorkomt ook geen HTML input.
Nogal wiedes, parametrized SQL queries beschermt tegen problemen in het SQL taaldomein. Voor elk taaldomein waar je input belandt is een eigen oplossing.
Driemaal raden wat een buffer overflow veroorzaakt? Juist een tekenreeks welke langer is dan verwacht? Dus geen controle bij invoer.
Nee, onveilig embedden. Het probleem is "kopieer X karakters van een string met lengte X naar buffer met grootte Y". Maak daarvan "kopieer min(X,Y) karakters van een string met lengte X naar buffer met grootte Y", en ineens is er geen buffer overflow meer. Of beter nog, misschien kan het wel met een variabele-grootte buffer. Zo komen buffer overflows vrijwel nooit voor in talen die geen strings van vaste lengte hebben (zoals Python, Perl, of PHP).
Om het eens over een andere boeg te gooien: wat als in jouw C programma invoer langs twee buffers komt, één van 16384 bytes, en één van 4096 bytes. Invoer gebeurt op 2 verschillende plaatsen. Overal controleer je netjes of de invoer korter is dan 4096 bytes. Nu verklein je één van die twee buffers, of de data moet voortaan ook langs een nieuwe, kleinere, buffer van 1024 bytes. Dan moet je er dus aan denken om de invoerchecks aan te passen op beide invoerlocaties (als je er al uberhaupt aan denkt om de invoerchecks aan te passen). De lengte van de buffer moet op twee hele andere plaatsen bekend zijn, namelijk bij de buffer zelf, en bij de invoercheck.
Maar als je nou bij elk van de drie buffers strncpy() met de juiste lengte gebruikt om zo buffer overflows te voorkomen? Dan hoef je bij het toevoegen van een nieuwe buffer niet na te denken of de maximale lengte daardoor korter wordt en of je je invoerchecks moet aanpassen en waar die ook alweer stonden. Je houdt de maatregel precies daar waar hij gebruikt wordt.
HTML injectie? geen controle bij invoer.
Nee, onveilig embedden. Escape de HTML bij het embedden, en injection verdwijnt.
SQL Injectie? Geen controle van invoer..
Nee, onveilig embedden. Gebruik parametrized queries, en de invoer wordt nooit als SQL beschouwd.