Valideren kun je leren

Door EdwinG op maandag 15 juni 2009 22:17 - Reacties (16)
Categorie: -, Views: 3.469

Een veelgebruikte methode om gebruikersinvoer te controleren op bepaalde eigenschappen is het toepassen van reguliere expressies.

Maar in plaats van het probleem van onbetrouwbare invoer op te lossen, komt er in veel gevallen juist een probleem bij: Zorgen dat de validatie precies doet wat het moet doen.

Zoals ik vandaag reeds in een reactie op een ander blog heb vermeld, is het niet noodzakelijk om het wiel opnieuw uit te vinden. De meeste validaties worden immers door veel meer personen gebruikt, waardoor er vaak over nagedacht is.

Ook zijn er voldoende verzamelingen te vinden van goed bruikbare expressies, zoals bijvoorbeeld De OWASP Regex Repository.

Natuurlijk blijft hetzelfde probleem bestaan. Een enkel karakter kan een wereld van verschil maken met reguliere expressies. Denk bijvoorbeeld maar aan het weglaten of toevoegen van een ^ teken aan het begin van de expressie. Enige kennis is daarom noodzakelijk om er zeker van de zijn dat de gebruikte expressie zijn doel bereikt (en niet voorbijschiet).

Enkele belangrijke karakters/eigenschappen zijn de volgende:
  • Een ^ aan het begin van de expressie geeft aan dat de onderzochte tekst moet beginnen met het gezochte patroon.
  • Een $ aan het einde van de expressie geeft aan dat de onderzochte tekst moet eindigen met het gezochte patroon.
  • Tekens die tussen [ en ] staan: Een teken uit deze groep moet aanwezig zijn.
  • . een willekeurig karakter
  • + Het teken (of de groepering) voor de + moet minstens 1 keer voorkomen
  • * Het teken (of de groepering) voor de * mag een willekeurig aantal keer voorkomen (ook 0 keer)
  • ? Het teken voor de ? is optioneel ( 0 of 1 keer voorkomen)
  • {x,y} Het teken of de reeks voor de { } moet minstens X en maximaal Y keer voorkomen
Maar het belangrijkste is wel: Wees kritisch bij het gebruik van reguliere expressies. Als er eenvoudigere alternatieven zijn, gebruik die dan. Om bijvoorbeeld te controleren of de invoer een getal is, zal is_numeric() (php) of een dergelijke functie eenvoudiger en sneller werken.

Volgende: Advanced PHP, maar dan anders 10-'10 Advanced PHP, maar dan anders
Volgende: Gratis: 6 (of 2?) onbeveiligde vrienden 02-'09 Gratis: 6 (of 2?) onbeveiligde vrienden

Reacties


Door Tweakers user mithras, maandag 15 juni 2009 22:34

Naar mijn idee zijn regexen overrated. Iedereen gebruikt ze overal voor, terwijl er vele alternatieven zijn die sneller zijn en/of beter in onderhoud. Ik gebruik zelf ook nooit regexen, maar zal altijd met simpeler methoden werken. En als je vervolgens de data op de juiste manier escaped, zullen er eigenlijk geen problemen optreden ;)

Door Tweakers user robrt, maandag 15 juni 2009 22:37

Handig, dat maakt regexps weer een stukje makkelijker. Thanks! :)

Door Tweakers user TeeDee, maandag 15 juni 2009 22:54

* TeeDee wijst nog eventjes op de signature vanCreepy

Je laatste alinea maakt alles weer goed! :>

Door Tweakers user HyperBart, maandag 15 juni 2009 23:12

ZO zitten Regexen dus in mekaar :o (serieus...)

Door Tweakers user Trinsec, maandag 15 juni 2009 23:17

Ik vind regexpen leuke dingen, maar je moet inderdaad wel weten wanneer het WEL of NIET handig is.

Meestal zie je een leuke trend onder mensen die nog net met regexp beginnen, dan zie je dat ze daadwerkelijk alles in een regexp proberen te dumpen (deed ik ook :D). En dan komt later het besef van.. eeeeuh... dat had veel makkelijker in een NIET-regexp dingetje gekund. En daarna zie je 'dat moet regexp, dat niet' beter gebruikt. Nouja, sommige mensen zullen het nooit leren, ik ken iemand die echt alles te moeilijk wilt maken. :P

Door Tweakers user MartijnDwars, maandag 15 juni 2009 23:28

Dat het leuke dingen zijn ben ik met je eens, maar ik heb soms het idee dat het een taal apart is. Overzichtelijk vind ik die dingen niet en ik weet ook nooit hoe ik ze zelf op moet bouwen (terwijl ik toch al een jaartje of 5 in PHP programmeer). Vandaar dat ik enkel reguliere expressies gebruik bij het filteren van bijvoorbeeld content van een website. Valideren van veelgebruikte userinput kan met de komst van PHP5.2.0 gelukkig met de functie filter_var.

Door Tweakers user crisp, maandag 15 juni 2009 23:29

Het is altijd maar de vraag of de reguliere expressies, zelfs die waar 'over nagedacht' zijn, wel precies doen wat je wilt. Over het algemeen doen ze namelijk maar ongeveer wat je wilt en zijn het slechts filters die nog steeds mogelijke invalide input doorlaten (en in een enkel geval ook valide input als incorrect bestempelen). Ik zie op de OWASP pagina die je linkt zo al dat de eerste 3 expressies (url, IP en e-mail) gewoon niet RFC-compliant zijn...
Valideren van veelgebruikte userinput kan met de komst van PHP5.2.0 gelukkig met de functie filter_var.
De filter_var validatiefuncties zijn ook alles behalve perfect...

[Reactie gewijzigd op maandag 15 juni 2009 23:31]


Door Tweakers user pat42, maandag 15 juni 2009 23:55

terwijl er vele alternatieven zijn die sneller zijn en/of beter in onderhoud
Ik ben wel benieuwd waar je op doelt. Natuurlijk zijn regexen niet nodig om te kijken of iets een nummer is (zoals de typefreak al noemt), maar soms wil je toch echt wel regexen gebruiken (UBB codes omzetten naar html bijvoorbeeld).
Daarnaast is het inderdaad de vraag in hoeverre je php functies als filter_var() kan vertrouwen, zoals crisp al aangeeft.

Door Tweakers user kipusoep, dinsdag 16 juni 2009 00:31

Helemaal mee eens met de twee reacties hierboven...
En wat dacht je van url rewriten? Daar moet je echt wel regex voor gebruiken en in zo'n geval, mits je het een beetje kent, is het ideaal!

Een geweldige site om je regex mee op te bouwen / te testen / te leren: http://gskinner.com/RegExr/

Door Tweakers user crisp, dinsdag 16 juni 2009 00:35

maar soms wil je toch echt wel regexen gebruiken (UBB codes omzetten naar html bijvoorbeeld).
Daar wil je het liefst een tokenizer voor gebruiken met daar bovenop een stack-based parser ;)

Door Tweakers user AndriesLouw, dinsdag 16 juni 2009 00:50

is_numeric()? Dan wel gelijk goed graag, en ctype_digit() ;)

Maar verder mooie post!

Door Tweakers user RobIII, dinsdag 16 juni 2009 00:55

(UBB codes omzetten naar html bijvoorbeeld).
Dan wil je juist geen regex gebruiken maar een stack based parser bijvoorbeeld.
edit:
Crap; crisp's reactie niet gezien :P
En wat dacht je van url rewriten? Daar moet je echt wel regex voor gebruiken en in zo'n geval
mod_rewrite is gebaseerd op regexes ja; maar dat is maar 1 implementatie. Ik heb mijn eigen "mod_rewrite" systeempje op classic(!) ASP hartstikke leuk draaien zonder 1 regex.

[Reactie gewijzigd op dinsdag 16 juni 2009 00:57]


Door Tweakers user Barleone, dinsdag 16 juni 2009 01:05

regex mist voor mij een belangrijke feature. stel het volgende voor:

input moet zijn: 'baas' of 'boos'.

Dan wil ik dat als volgt kunnen checken:

eerst een b
(dan twee aa's
- of -
twee oo's)
dan een s

maar ik wordt verplicht mijn regex als volgt op te bouwen:

eerst een b
dan twee aa's
dan een s

- of-
eerst een b
dan twee oo's
dan een s

Door Tweakers user driek.org, dinsdag 16 juni 2009 05:32

@barleone: standaard reguliere expressies kunnen dat gewoon:
/b(aa|oo)s/
http://en.wikipedia.org/wiki/Regex#Basic_concepts

Door Tweakers user H!GHGuY, dinsdag 16 juni 2009 12:39

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

Door Tweakers user analog_, zondag 10 oktober 2010 18:32

Opvallend is ook de bijzonder beroerde regex kennis onder bachelor IT studenten. Ik ken geen enkele opleiding in belgie waar dit deel uit maakt van het curriculum terwijl vaak complexere problemen hier eenvoudig(er) mee op te lossen zijn.

Als je met regex begint kan je trouwens best een speciaal tootje installeren, ik vond regexbuddy bijzonder gemakkelijk om snel iets op te stellen.

[Reactie gewijzigd op zondag 10 oktober 2010 18:34]


Reageren is niet meer mogelijk