Regex omdraaien
Ik gebruik de volgende regex om te controleren of de input iets anders bevat dan toegestaan (a-Z0-9 punt, komma, singlequote, dash en <br>).....
Ik ben aan het proberen geweest om een soortgelijke regex te maken om user input op te schonen voor output. het lukt alleen niet echt en heb al verschillende dingen geprobeerd. Na een paar uur hacken ben ik bang dat ik me er een beetje blind op staar....de reeks van geprobeerde dingen is eindeloos maar hier een paar die redelijk lijken.
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
$regex_char_appearance = '/(?!<br>)([^A-Za-z0-9 \-\.\,\'])/';
$regex_char_appearance = '/[^A-Za-z0-9 \-\.\,\']|[^(<br>)])/';
?>
$regex_char_appearance = '/(?!<br>)([^A-Za-z0-9 \-\.\,\'])/';
$regex_char_appearance = '/[^A-Za-z0-9 \-\.\,\']|[^(<br>)])/';
?>
het doel is dus om alles behalve [a-Z0-9], punt, komma, singlequote, dash en <br> te verwijderen voor output met preg_replace.
Kan iemand mij helpen een regex samen te stellen die werkt?
Is dit bijvoorbeeld om ervoor te zorgen dat berichten in een soort van gastenboek geen HTML of andere ongein bevatten? In dat geval zou je de output ook op andere manieren onschadelijk kunnen maken binnen de "HTML context" zonder eisen te stellen aan de invoer.
De output komt als tekst in beeld en word opgeslagen in een DB.
Later kan dit weer bewerkt worden in een textbox.(voor in de textbox word <br> tijdelijk omgezet naar \r\n)
Op deze manier leg je geen restricties op aan wat mensen kunnen invoeren, wat eigenlijk wel zo fijn is.
Oftewel: in plaats van het stellen van allemaal eisen aan de invoer, maak simpelweg de uitvoer onschadelijk.
Eigenlijk wil ik dat wel voor ik het op sla in de DB zodat ik me daarna niet al te druk hoef te maken om de output.... Daarom zet ik alle regelovergangen om in <br>. Verder hoeven gebruikers niks anders te gebruiken dan reguliere tekst en cijfers, punt, komma, dash en singlequote.
Het beste is meestal om de informatie zoveel mogelijk in zijn oorspronkelijke/rauwe toestand op te slaan en de wijzigingen die nodig zijn voor weergave zo laat mogelijk door te voeren, bijvoorbeeld pas op het moment dat je de gegevens op het scherm toont.
en misschien kunnen we even terug naar de topic Thomas...;) De regex?
Misschien omdat je later een ander systeem implementeert, waardoor je wél de originele input nodig hebt, of misschien wel om te kunnen constateren dat iemand bezig is geweest om je systeem te hacken.
>> en misschien kunnen we even terug naar de topic Thomas...;) De regex?
Die heb je dus wellicht niet (in die vorm) nodig. Dat is wat Thomas je probeer uit te leggen.
Om terug te komen op je regexp: deze "werkt" waarschijnlijk niet omdat je niet heel je invoer matcht. Je kijkt enkel of er toegestane karakters in voorkomen. Om af te dwingen dat de gehele invoer bestaat uit jouw karakter-whitelist (wat mij dus nog steeds geen goed idee lijkt) moet je de gehele invoer matchen. Dit doe je door dat in je patroon aan te geven middels <delimiter>^<je patroon>$<delimiter>.
^ wil zeggen: match patroon vanaf het begin van de invoer
$ wil zeggen: match patroon tot het eind van de invoer
Ook zou ik mensen geen breaks laten typen. Dit is een weergave probleem wat ondervangen kan worden door nl2br(). Daarnaast zou je de expressie case-insensitive kunnen maken met de i-switch (toevoegen na je <delimiter>).
Maar je begeeft je al snel op een hellend vlak met zo'n beperkt karakter-repertoir. Karakters met accenten vallen al buiten de boot, dubbele punten en puntkomma's staan er niet tussen. Ga je dan elke keer karakters toevoegen als blijkt dat het toch handig is om deze toe te staan? Het is gewoon niet praktisch.
Bij mij in het gezin zijn 3 namen met een accent op een letter.
Daarnaast zou iemand mogelijk iets met een bedrag willen noemen. Een Euro-teken zou dus zo maar kunnen.
En heel raar zijn de volgende tekens niet: de dubbele punt, de puntkomma. En een emailadres mag kennelijk ook niet opgeslagen worden?
Kortom: je sluit een heel stel tekens uit die volkomen onschuldig zijn, maar wel heel goed in een tekst kunnen staan.
Je verzint nu een beveiliging op de verkeerde plek.
De data die de bezoeker intikt, wil je zo rauw mogelijk in je database hebben. Bijvoorbeeld die Enter: als je daar direct een <br> van maakt, dan zit je dus met het probleem dat als hij de tekst nog eens wil bewerken, je de invoer vervuild hebt en dus die <br> weer naar een enter terug moet zetten.
Ook als je een email wilt maken van deze tekst, of een pdf of misschien wel een Excel-sheet, zit je met die <br> in je maag.
Kortom: je beperkt je nogal. terwijl braaf overal in combinatie met echo htmlspecialchars() gebruiken je probleem ook oplost.
Ik zoek nog wel verder.
de functie htmlspecialchars() hoeft toch niet gezocht te worden?
Waar jullie tegen aan kijken is 1 regel code van een uitgebreid script voor een spelletje. Ik doe dit als hobby en dingen later aanpassen is geen probleem. Ik heb geen haast....
Wat mij nog al stoort is dat jullie geen idee hebben van het hele plaatje en wat het exacte doel is...toch nemen jullie aan dat wat jullie zeggen wat ik nodig heb om te bereiken wat ik wil. Het hele plaatje is te uitgebreid om uit te leggen en de kans is groot dat jullie de helft niet lezen. Zoals nu. Er komen (en hoeven) geen namen in of eurotekens of andere dingen....dat is een aanname. E-mails die worden op een andere pagina ingevoerd en verwerkt. De gebruiker hoeft geen tags in te voeren die kan gewoon enteren in een textbox...iemand heeft dat aangenomen. Ik heb bijna letterlijk gezegd dat ik zelf alles omzet naar 1 tag. Het heeft niets met beveiliging te maken...hoewel het niet eens onveilig is. Waarom zou ik "<script>alert("hacked")</script>" op willen slaan? Waarom zou ik Scheiße of señor opslaan als er in het engels gecommuniceerd word...
Als je iemand iets wil leren luister(lees) dan eens goed naar de vraag...ik vraag niet naar HTML! HTML is wel het doel....ik vraag naar PHP en PCRE syntax.
Ik kwam hier omdat ik me blind staar op de opbouw van een regex...succes mannen maar morgen ga denk ik weer naar stackoverflow.com!
doei...;)
Het grappige is dat je zelf het exacte doel niet aangeeft en dan een ander ervan beschuldigt dat ie niet leest. Waar gaat dat mis denk je? Bij een ander of bij jezelf? Met dat gedrag ben je op SO al helemaal niet welkom.
Dus iemand die Engelstalig spreekt kan niet José heten? Een Nederlander genaamd Ariën is niet welkom op de website? Enz. ??
Niemand hier probeert je te pesten ... we proberen alleen je intenties te begrijpen. Als jij daar niet voor openstaat ... tja ...
Ik denk dat dat ook juist het probleem is.
Je bent nu zo gefocust op deze regex, dat je in een tunnel terecht bent gekomen.
Ik snap je benadering prima. (afgezien van die <br>, want als je gebruiker gewoon een enter mag typen, dan vult jouw script dus met nl2br() die <br>. En dan had je regex dus vóór nl2br() moeten staan).
En ja: als iemand alleen maar letters mag typen, zullen er weinig fouten kunnen optreden. Behalve dan als iemand een copy-paste doet van de hele php-handleiding, want dat gaat weer niet passen in je database (hoop ik).
Maar je blokkeert zoveel meer dan nodig is. En hierboven staan al zat voorbeelden van tekens die jij niet toestaat, maar die volkomen onschuldig zijn en waarvan je heel goed voor kunt stellen dat ze wel zinnig zijn in de invoer.
http://stackoverflow.com/questions/36737766/how-do-i-flip-a-regex
Ongeveer 40 minuten...opgelost. En wat te lezen/leren.
@Ben. Ik bedoel het echt niet slecht. Het doel is in de eerste post al aangegeven. een regex die het tegenovergestelde doet van wat al mogelijk is. characters niet toelaten...en verwijderen met preg_replace.
@Ozzie. Ik voel me niet gepest. nogmaals...er komen/horen geen namen in. ;)
@Ivo. Ik ben idd gefocused omdat ik een doel heb. Nogmaals...de gebruiker hoeft geen <br> te typen. En als iemad een c/p doet gaat het door deze regex. mb_strimwidth zorgt er voor dat het niet langer word dan ik wil en in de DB in takt blijft.Wil je nog meer weten of is het goed zo? ;)
Bedankt voor jullie tijd! kusje! :D
Ongeveer 40 minuten...opgelost. En wat te lezen/leren.
@Ben. Ik bedoel het echt niet slecht. Het doel is in de eerste post al aangegeven. een regex die het tegenovergestelde doet van wat al mogelijk is. characters niet toelaten...en verwijderen met preg_replace.
@Ozzie. Ik voel me niet gepest. nogmaals...er komen/horen geen namen in. ;)
@Ivo. Ik ben idd gefocused omdat ik een doel heb. Nogmaals...de gebruiker hoeft geen <br> te typen. En als iemad een c/p doet gaat het door deze regex. mb_strimwidth zorgt er voor dat het niet langer word dan ik wil en in de DB in takt blijft.Wil je nog meer weten of is het goed zo? ;)
Bedankt voor jullie tijd! kusje! :D
Een oplossing voor een nodeloos lastig probleem: immers de gebruiker voert geen <br> in, maar Enter.
Daar had je dus een heel veel simplere regex gehad als je voor nl2br() de check deed.
Maar daarnaast heb je nu een oplossing voor een non-probleem. Er kan geen enkel serieus probleem optreden als iemand in zijn profiel een é een puntkomma en een ! zou hebben staan.
zelfs een < en een " zou onschuldig zijn, als je maar netjes overal htmlspecialchars gebruikt.
Ik denk dat de meeste mensen die hierboven gereageerd hebben, in gedachte houden dat je over een aantal weken tóch letters met accenten nodig hebt.
En dat kort daarna blijkt dat je ook een ! en ? wel handig vindt.
En dat je dan dus eigenlijk je filter steeds meer oprekt tot een situatie die je ook bereikte met htmlspecialchars.
Geloof me: het komt best veel voor dat de beschrijving van de probleemstelling "het is altijd A óf B" na oplevering door de klant wordt bijgesteld naar "ja, maar behalve als C, en soms komt D ook voor maar dan wel gelijktijdig met B"
Maar goed.
Vermoedelijk ga je voorlopig even blij zijn met je regex.
Ah well.