8711 sujets

Développement web côté serveur, CMS

Bonjour à tous,

Je dispose d'un formulaire que je souhaite valider et sécuriser avant de soumettre celui-ci, sachant que la soumission (via le "submit") envoie les données vers une Base de données.

Voici le formulaire

    <form name="formulaire" method="post" action="insert.php">
    <p>
    <label for="dateActu">Date à laquelle se déroule l'actualité</label> 
    <input type="[b]date[/b]" name="date" size="30"/>
    </p>
    <p>
    <label for="lieuActu">Lieu où se déroule l'actualité</label> 
    <input type="text" name="[b]lieu[/b]"  size="30"/><br/>     
    </p>
    <p>
    <label for="intActu">Nom de l'intervenant</label> 
    <input type="text" name="[b]intervenant[/b]" size="30"/><br/>
    </p>
    <p>
    <label for="sujetActu">Sujet de l'actualité</label> 
    <input type="text" name="[b]sujet[/b]" size="30"/><br/>
    </p>
    <p>
    <input type="submit" value="Soumettre">   
    </p>
    </form>

    <?php
    if(empty($_POST["date"]) || empty($_POST["lieu"]) || empty($_POST["intervenant"]) || empty($_POST["sujet"])) {
    echo "Vous devez compléter tous les champs du formulaire !";
    }
    ?>


La dernière ligne est le début de ma réflexion concernant la validation du formulaire mais elle est pour l'instant parfaitement inutile puisque je n'ai pas ajouté de condition.

Je vous fais une liste de ce que je souhaite implémenter pour les champs :

- "Date" : ne pas pouvoir ajouter de champ texte, ni de caractères spéciaux même si normalement le fait que le type du champ soit date le fait tout seul, la fonctionnalité n'est pas présente sur tous les navigateurs et permet une faille si je ne le sécurise pas.

- "Lieu" : je souhaite que l'utilisateur qui remplit ce champ puisse mettre un lien de ce type

<a href="lelien.html">Le lieu où se déroule l'actu</a>


J'imagine que c'est ce champ qui va poser le plus de problème, étant donné que l'injection de code dans un formulaire est quelque peu houleuse. Je ne vois pas trop comment aborder la chose pour l'instant.

- "Intervenant" et "Sujet" : pas de caractères spéciaux pour ces champs, je pense que ça suffira.

Enfin je souhaite que tous les champs soient remplis pour pouvoir permettre l'envoi du formulaire, je sais que c'est la fonction !empty qui permet ceci mais j'ignore comment la mettre en place pour mon cas.

Je précise que j'ai plus ou moins une idée de comment réaliser la chose mais je n'arrive pas réellement à mettre en forme mes idées puisque je suis un peu à la ramasse en PHP pour l'instant Smiley confus .

Merci d'avance à tous et bonne journée !

PS : J'ai ouï-dire qu'une bonne pratique consistait à sécuriser le formulaire une première fois côté client avec du Javascript, puis une seconde fois côté serveur en PHP/Mysql. Ai-je besoin de rajouter une couche supplémentaire Javascript ou puis-je faire d'une pierre de coup en sécurisant seulement PHP/Mysql ?
Modifié par georgelarace (26 Apr 2013 - 11:27)
Pour commencer par la fin:
Sécuriser un formulaire par javascript permet aux utilisateurs de ne pas avoir à subir de rechargement de page pour voir leurs erreurs. Ce n'est pas indispensable, mais c'est un "plus". Par contre, la vérification par PHP ne doit pas être négligée, en effet, ces données vont vers une machine, et une machine peut être endommagée par un utilisateur mal intentionné (même si dans ton cas les données ne sont pas très sensibles).
Pour contrôler tes champs de texte, tu va devoir apprendre les Regex Smiley lol
C'est un objet qui peut être un peu dur à aborder, mais une fois qu'on le maîtrise, on ne peut plus s'en passer ! Mais de quoi s'agit-il ? Selon moi, une regex s'assimile à une "forme" de chaîne de caractère, c'est à dire qu'elle va pouvoir reconnaître un certain nombre de chaînes selon des critères définis.
Exemple: "j'ai 23 ans" et "je vis depuis 57 ans"
C'est deux chaînes véhiculent une information facilement identifiable par un humain, pourtant, une machine ne peut pas l'interpréter. Alors, il faut repérer les similtudes qui lient ces deux chaînes; la plus frappante: il y aura forcémment un nombre. Alors en admettant (pour faciliter les choses) que l'utilisateur donnera toujours son âge par valeurs chiffrées, de la même manière que nos deux exemples, on peut réussir à les identifier: c'est là que les regex interviennent, il existe deux manières (je crois Smiley rolleyes ) d'identifier des nombres: "[0-9]" et "\d"
Il existe aussi des manières de définir le nombre de caractères numériques recherchés, ici, nous utiliserons "+" qui cherche un caractère présent 1 fois ou plus dans la chaîne.
Enfin, une regex est toujours calibrée entre deux caractères délimiteurs, moi j'utilise (en php) le dièse "#".
Notre regex: #\d+# ou #[0-9]+#
Voilà, cette regex cherche 1 ou plusieurs chiffres dans une chaîne de caractères.

Mais cette mise en bouche ne te sera pas suffisante pour ton formulaire, je te conseille de cherche "regex" sur le site du zero, il y a un très bon tuto.

Si tu a besoin d'aide, n'hésite pas à me demander Smiley cligne
Bonjour,

PHP dispose de plusieurs fonctions dédiés à cela dont filter_var.
http://fr2.php.net/manual/fr/function.filter-var.php

Voici un exemple pour les emails :

$var = 'email@domain.tld';
$result = filter_var($var, FILTER_VALIDATE_EMAIL);
var_dump($result); // output : string(16) "email@domain.tld"
 
$var = 'email@domain';
$result = filter_var($var, FILTER_VALIDATE_EMAIL);
var_dump($result); // output : bool(false)


Les valeurs possibles sont : FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_INT, FILTER_VALIDATE_IP, FILTER_VALIDATE_REGEXP, FILTER_VALIDATE_URL.

Voici un article avec plein d'exemples : http://phpchunk.net/2011/06/validate-sanitize-data-php-filter-part-1/

PS : Il faut toujours utiliser une fonction PHP avant d'avoir recours à des regExp. C'est beaucoup plus performant.
Modérateur
juliendargelos a écrit :

Sécuriser un formulaire par javascript permet aux utilisateurs de ne pas avoir à subir de …


Argggghh non! Jamais, on ne peut pas sécuriser un formulaire en javascript. QUE en PHP, mais on peut faire de la validation tout de même, voici un résumé des étapes qui peuvent êtres considérées séparément pour bien comprendre, tous sont bien entendu nécessaires du côté serveur:

1) Sécurité: injection. Inutile en javascript. Enfin pourquoi coder plus pour être user-friendly envers quelqu'un qui tente de corrompre vos données, de s'introduire dans votre système ou de tricher sur certains aspects?
2) intégrité simple: Vérifier que les données puissent être introduites correctement dans la base de donnée et que leurs valeurs soient cohérentes. On ne peux pas (enfin parfois si…) être né en 2032, on attend 156 comme valeur de taille de pantalon et non pas 'L', etc. Cette validation permet d'éviter:
- Données incohérentes en Base pouvant provoquant des bugs
- Exploitation de faille en se servant de ces bugs
- Erreurs SQL
L'intégrité simple peut souvent se vérifier facilement par javascript, bien que cela reste optionel
3) intégrité complexe #1: Valeurs possibles seulement selon d'autre champs. Généralement géré par des selects. exemple: pays>région>ville. Là le javascript peut être salutaire car le champ comprenant toutes les villes possibles Smiley langue
4) intégrité complexe #2: Intégrité relative à des valeurs stockées en DB. Champs à valeurs uniques (login/e-mails), Association de champs uniques, etc. Là le javascript peut être plus complexe car nécessite souvent de l'Ajax, mais dans certains cas cela reste très pratique.

Quant à savoir quoi implémenter côté JS, il faut se poser quelques bonnes questions. Cela dépend:
- création de compte: login. Ce login est déjà pris. L'utilisateur n'est pas devin, c'est sympa de lui éviter 50 rechargement de page.
- Dates: Une date de fin avant une date de début. Mon ami, si tu ne suis pas les instructions ramasses un rechargement de page!


arnolem a écrit :
PS : Il faut toujours utiliser une fonction PHP avant d'avoir recours à des regExp. C'est beaucoup plus performant.

Oui mais non. Ce n'est pas tout à fait vrai. ça l'est pour des opérations simples et uniques de recherche et remplacements. Pour d'autre cas pas. En plus filter_var utilise derrière des regExp ^^. L'avantage ici est d'éviter d'utiliser une des regexp bricolées et fausses circulant sur le net, mais plutôt une issue des longs échanges entre spécialistes pour l'affiner et la corriger. ainsi:

var_dump(filter_var("!#$%&'*+-/=.?^_`{|}~@[1.0.0.127]", FILTER_VALIDATE_EMAIL)); // passe
var_dump(filter_var('"moi@alsacreations.com"@mon.truc', FILTER_VALIDATE_EMAIL)); // passe


Alors que parmi les tonnes de regexp mal faites circulant ça ne passerait jamais!
kustolovic a écrit :
Argggghh non! Jamais, on ne peut pas sécuriser un formulaire en javascript.

À tu lu ma phrase en entier ?
juliendargelos a écrit :
Sécuriser un formulaire par javascript permet aux utilisateurs de ne pas avoir à subir de rechargement de page pour voir leurs erreurs. Ce n'est pas indispensable, mais c'est un "plus". Par contre, la vérification par PHP ne doit pas être négligée, en effet, ces données vont vers une machine, et une machine peut être endommagée par un utilisateur mal intentionné (même si dans ton cas les données ne sont pas très sensibles).
Je veux dire par là que la vérification en javascript n'est qu'un artifice supplémentaire qui permet de donner un aspect plus dynamique à l'interface. Je ne veux en aucun soutenir que l'on peut se passer de PHP !!
Modifié par juliendargelos (09 May 2013 - 22:33)
Oula j'étais pas retourné sur ce post depuis un bail, en tout cas merci pour vos réponses, ça me donne de la matière à explorer Smiley cligne .
kustolovic a écrit :
var_dump(filter_var(&quot;!#$%&amp;'*+-/=.?^_`{|}~@[1.0.0.127]&quot;, FILTER_VALIDATE_EMAIL)); // passe
var_dump(filter_var('&quot;moi@alsacreations.com&quot;@mon.truc', FILTER_VALIDATE_EMAIL)); // passe


Alors que parmi les tonnes de regexp mal faites circulant ça ne passerait jamais!

La question est plutôt de savoir si la tonne de regexp mal faites laisseront passer les adresses véritables. Quelques exemples qui bloquent régulièrement :

- TLD en 2 lettres (blabla@blabla.be)
- TLD en 4 lettres (ou plus) (blabla@blabla.info / blabla@blabla.museum)
- TLD en 2 parties (blabla@blabla.ac.be/blabla@edu.be)
- nom de domaine avec un tiret ou un underscore (blabla@bla-bla.com / blabla@bla_bla.com)
- nom avec tiret, point, plus ou underscore (bla-bla@blabla.com / bla_bla@blabla.com / bla+bla@blabla.com / bla.bla@blabla.com)

Je te renvois d'ailleurs à cet article sur la problématique de l'interdiction des emails
Modifié par Lothindil (14 May 2013 - 17:06)
Modérateur
Pas mieux Smiley langue

Aller, pour le fun, voici la regex qui se cache derrière filter_validate_email, dans les dernières versions de php:

/^(?!(? [decu]?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(? [decu]?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(? [decu]?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(? [decu]?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(? [decu]? [decu]?!.*[^.]{64,})(? [decu]? [decu]?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(? [decu]?:[a-z][a-z0-9]*)|(? [decu]?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(? [decu]?:IPv6 [decu]? [decu]?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(? [decu]?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?: [decu]?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(? [decu]?:IPv6 [decu]? [decu]?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(? [decu]?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?: [decu]?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(? [decu]?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(? [decu]?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD


EDIT: enfin, officiellement, il y a moins de smiley!
Ligne 525: http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/logical_filters.c?revision=320369&view=markup&pathrev=320369
Modifié par kustolovic (15 May 2013 - 00:13)
jb_gfx a écrit :
Lothindil je pense que tu as mal compris Kustolovic. Smiley cligne

Non, je précisais que la question était (à mon goût et à celui de l'auteur que j'ai cité) moins de savoir si y avait des trucs pas corrects qui passaient que si des trucs corrects étaient passés ^^

Je complétais en fait son post en ajoutant des exemples plus classiques (ou du moins moins extrême) qui sont traditionnellement éliminés avec les regex mal foutues qu'on trouve partout ^^

(je le reconnais, j'ai pas été claire dans mon début de post Smiley biggol )