Google+ Followers

donderdag 5 november 2015

Input validatie en query-escaping

Onlangs had ik op phphulp een discussie met iemand die de uitspraak deed dat "een waarde die door je input-validatie heen komt in principe niet ge-escaped hoeft te worden in de query" .


Wat hij bedoelde, zo bleek later, was dat getallen geen tekens bevatten die behandeld moeten worden om in een query gebruikt te kunnen worden. Ergo; als je een input hebt kunnen valideren als zijnde een getal, dan is escapen voor die waarde niet strikt noodzakelijk.


Strict genomen is dat waar; je hoeft getallen niet te bewerken om ze in een query te zetten.
Maar wat heb je aan deze kennis?

Helemaal niets.






Zie hoe ik het woord getallen overal benadruk: de stelling gaat alleen op voor
getallen, niet voor strings of expressies die uit meer dan alleen cijfers bestaan. Het is niet mogelijk om een achternaam zo te valideren dat er alleen waarden uit komen die veilig zijn in een query. Dat zou Jaques 'd Ancona niet leuk vinden.


Daarbij valideer je de data voordat je de data gaat bewerken en tijdens die bewerking kan de gevalideerde data zo worden aangepast dat hij niet meer veilig is voor een query.

Tot slot is er altijd de mogelijkheid dat de data die de query ingeduwd wordt niet eens uit de validatie vandaankomt, een simpele tikfout in de naam van een variabele en je zit ongevalideerde data in te voeren.


In de praktijk zul je dus altijd moeten escapen, ongeacht welk type data je validatie zegt te hebben gevonden. Om die reden hebben databases het principe van het prepared-statement bedacht. Bij een prepared statement geef je de query syntax en de waarden die je in de query wilt gebruiken apart op, zodat de queryparser niet zelf hoeft uit te zoeken waar de data begint en eindigt.

"Jamaar, hij zegt toch ook 'in principe'"?

Klopt, en of je begrijpt wat hij daarmee bedoelt hangt helemaal van jou af. Er zwerven op het net heel wat PHP-classes rond die de data die naar een query wordt gestuurd door dingen als is_numeric heen halen om te bepalen of ze wel of niet moeten escapen en quoten. Waarom? Omdat ze ooit hebben gehoord dat getallen "in principe" niet ge-escapet of gequote hoeven te worden. Er worden potentiele beveiligingsgaten ingebouwd door dit soort slechtgeformuleerde uitspraken.

"Wat is dan het nut van input-validatie?"

Het nut van input validatie staat buiten kijf, het is *de* manier om te zorgen dat de data die je krijgt aangeleverd zinnig is. Als je een postcode verwacht en er staat "hallo hier Hilversum" in, dan kun je de verdere verwerking overslaan want de data is onzin.

Maar input validatie heeft *niets* te maken met queries of escaping. het is puur en alleen bedoeld als eerste controle om te zien of je data is wat je verwacht.