Hallo allemaal,

Dit is eerder een vraag om advies over veiligheid.
Ik merkte deze functies onlangs op:
$sanitized_a = filter_var($a, FILTER_SANITIZE_EMAIL);

Dus je kan input filteren tegen sql injectie bvb.

Nu vraag ik mij af of dit even veilig is om te gebruiken als de zelfgemaakte functies gelijk in wordpress.
Ruben D op 28/12/2017 17:11:07

Dus je kan input filteren tegen sql injectie bvb.

Daar is deze functie niet specifiek voor bedoeld. Deze functie probeert van een string nog een geldig emailadres te maken. Om SQL injection tegen te gaan kun je beter gebruik maken van bv. PDO en Prepared Statements

Ja dat klopt, met "FILTER_SANITIZE_STRING" dan.
Ik zou het ook zo doen maar wou weten of dit daar ook tegen helpt.
Een verkeerd gebruik van prepared statements is nog steeds even fataal (denk bijvoorbeeld aan het concateneren van lappen SQL waarmee je in wezen het prepared-statement-stramien bypassed). Het grootste probleem is dat iemand zich op een zeker moment veilig waant enkel door het gebruiken van een bepaalde techniek (lees: goocheltruc), zonder dat men precies weet wat de gevaren nu eigenlijk zijn. Als je niet weet wat een hondendrol is weet je ook niet wanneer je er in staat. En dan heb je letterlijk stront.

SQL injectie voorkom je ook niet (altijd) simpelweg door het filteren van input, tenzij deze heel strict is. Wat veel beter werkt tegen SQL injectie is output escaping. En vaak gaan input filteren en output escapen hand in hand.

Desalniettemin zijn dit twee compleet verschillende dingen.

EDIT: en sanitizen is wéér iets anders, daarbij wordt vaak geprobeerd recht te buigen wat eigenlijk al krom is. Vergelijk dit met een typecast waarbij getracht wordt iets om te zetten naar een bepaald type waarbij alles wat onleesbaar is uit oogpunt van dat type wordt weggekapt. Maar daarmee was dus eigenlijk de invoer al ongeldig... Invoer is meestal gewoon GOED of FOUT, en niet MISSCHIEN-GOED-DUS-LAAT-IK-PROBEREN-ER-IETS-VAN-TE-BAKKEN.

> filter input, escape output
> mysql_real_escape_string() is geen wondermiddel
verkeerd als hier: (geen input filter)
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->execute([$_POST['name'], 29]);

of bypass gelijk dit denk ik dat je bedoeld?
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES ($name, ?)");

Ik dacht wel ergens gelezen te hebben dat mysqli escape eruit gaat bij recente versies.
Ik zal is kijke of ik het nog kan vinden.
Sowieso gebruik je nooit rechtstreeks $_POST variabelen in parameter binding.

Voordat je de waarden gebruikt om aan je insert query te koppelen, heb je alles gevalideerd (met bv. een EmailValidator class) en in orde bevonden.

Een andere optie, is werken met Value Objects, waarbij de validatie in de constructor plaatsvindt. Een Value Object voor een email adres kan er zo uitzien:


<?php
class Email
{
    private $email;

    public function __construct($email)
    {
        if ( ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException(sprintf('[%s] is not a valid email address', $email));
        }

        $this->email = $email;
    }

    public function __toString()
    {
        return $this->email;
    }
}
?>


Het voordeel van werken met Value Objects is, dat je in je hele codebase nu nog maar één plek voor het valideren van email adressen hebt, namelijk in de constructor van dat object.
Jan Koehoorn op 28/12/2017 20:51:17
Value Objects

Dit klinkt allemaal best zinnig enzo, maar hoe ga je dit inpassen in de validatie van formuliergegevens? Wanneer een exception gethrowd wordt, wordt de normale flow van het programma onderbroken.

Ik zou ook niet zeggen dat een exception hier op zijn plaats is, het ligt immers in de lijn der verwachting dat iemand (al dan niet per ongeluk) een verkeerd e-mailadres invult. Ook wil je dan niet dat alles gestaakt wordt maar idealiter krijg je dan gebruiksvriendelijke terugkoppeling over *alle* velden waar mogelijk iets mis mee is (en niet enkel de eerste waar ie op stuk loopt, denk aan JavaScript popups uit de jaren 90 :p).

Ik had ook eerder een berichtje in deze thread in een ander draadje geklopt hoe je exceptions zou moeten zien (als ik er (ver) naast zit hoor ik dat ook graag, ben benieuwd naar andere inzichten over exceptions).

Mogelijk zou een exception bijvoorbeeld (wel?) op zijn plaats zijn bij formulierafhandeling wanneer een CSRF-token niet meer klopt (of niet meer bestaat) bij validatie omdat dat echt iets "onverwachts/ongeplands" is. Maar zelfs dan heb je liever dat (wanneer je sessie onderwater weer hersteld is, want het is meestal zoiets als een verlopen sessie ofzo) je weer teruggestuurd wordt naar het formulier met de zojuist ingevulde informatie -ook al is deze goed- maar met de mededeling dat het token is verlopen en je nogmaals dient te submitten. Dat lijkt mij vriendelijker dan een aparte "oeps, er ging iets mis" pagina nadat je het afgelopen half uur een verhaal hebt zitten typen, en dat je dat dan kwijt bent.

Oftewel: ik zie niet zogauw hoe het (veelvuldig) gebruiken van exceptions een goed idee is bij formulierafhandeling/-validatie. Het is niet "fataal" als iemand iets verkeerds ingevuld heeft, noch is het dan onduidelijk wat er vervolgens zou moeten gebeuren.
@Thomas:

Ik vind dat ook wat lastig. Op het forum heb ik mensen wel eens horen (niet letterlijk) zeggen dat je beter overal exceptions kunt gebruiken (ipv if-statements). Ik vraag me dus ook wel af wanneer wel en wanneer niet. Mij lijkt het ook niet logisch om een fout e-mailadres af te vangen met een exception, en toch schijnt het te gebeuren.

Want eigenlijk is het natuurlijk best raar ... Je vangt een situatie die zich kan voordoen af met een exception ... maar als je weet dat de situatie zich kan voordoen ... in hoeverre is het dan nog een exception? En ... wanneer is iets dan überhaupt nog een exception? Iemand die een typfout maakt (veelvoorkomend gedrag) zie ik niet als een exception, iemand die een fout wachtwoord invoert ook niet. Dat is allemaal VOORSPELBAAR gedrag.

Maar wat zou dan wel een exception kunnen zijn ... Misschien een keuzeformulier dat als waarde A, B of C verwacht, maar X ontvangt? Dan is er sprake van iets onverwachts wat riekt naar een hackpoging, maar verder zou ik het zo gauw ook even niet weten.
Precies, maar dan zou je kunnen zeggen: ik heb een set A, B, C en hier moet een geldige keuze in gemaakt worden. Als je dan X krijgt is dat geen geldige keuze. Het is dan nog steeds duidelijk wat er zou moeten gebeuren (kies een geldige waarde).

Was dat niet ook op de DOS-prompt: de keuze-loop vliegt er toch ook niet uit als je iets anders dan [a]bort, [r]etry, [f]ail kiest? :)

Zoals ik het zie is een exception een soort van noodrem, waarbij de code zegt "ik kom er ff niet uit". Een hoger gelegen laag / ander stuk code beslist dan meestal wat er moet gebeuren. Dit is denk ik ook een kenmerk van exceptions: de plek waar aan de noodrem wordt getrokken is zelden tot nooit de plek waar dit verder wordt afgehandeld. Immers, dit zou namelijk inhouden dat de code al een soort van idee heeft van wat er mis is gegaan, en hoe hier mee omgegaan moet worden. Wat weer een indicatie is dat je hiervoor geen exception hoeft te/zou moeten gebruiken :).
Thomas van den Heuvel op 29/12/2017 01:20:47

[quote="Jan Koehoorn op 28/12/2017 20:51:17"]Value Objects

Dit klinkt allemaal best zinnig enzo, maar hoe ga je dit inpassen in de validatie van formuliergegevens?
[/quote]

Niet. Daar vul je gewoon een array met errors. Je zou trouwens wel kunnen denken aan een AJAX call op de onblur van een formfield, met daarin dan weer wél de check met het value object. Dan heb je userfriendly validation aan the client side en uiteraard check je altijd serverside. Ik zou dat alleen doen bij formulieren met veel velden. Dan is het wel prettig om meteen na het verlaten van het veld erachter te komen dat het invalid is, en niet pas bij het submitten van het formulier.
Thomas van den Heuvel op 29/12/2017 14:37:52

Precies, maar dan zou je kunnen zeggen: ik heb een set A, B, C en hier moet een geldige keuze in gemaakt worden. Als je dan X krijgt is dat geen geldige keuze. Het is dan nog steeds duidelijk wat er zou moeten gebeuren (kies een geldige waarde).

Ik snap wat je bedoelt ... maar stel we hebben 2 radiobuttons waarbij je kunt kiezen of je van een product de variant van € 50 wilt hebben, of de luxere variant van € 65.

Je kunt dus kiezen uit waarde € 50 of € 65. Stel dat je nu ineens als waarde € 1 krijgt (een keuze-optie die helemaal niet beschikbaar is), zou je dan niet een exception kunnen gooien? In dat geval heeft namelijk iemand handmatig de POST-data gewijzigd en is er blijkbaar sprake van een soort hackpoging. Dit gaat weer net iets verder dan simpelweg 'een ongeldige keuze'.

In zo'n geval zou ik misschien op een hoger niveau het IP-adres even willen blokkeren vanwege verdacht gedrag.

Reageren