web-dev-qa-db-fra.com

La validation du modèle d'entrée HTML5 est-elle suffisante (ou même pertinente) pour la validation côté client?

Une fonctionnalité intéressante de HTML5 est le <input pattern="" />attribut , qui permet au navigateur de valider la valeur du champ de saisie par rapport à une expression régulière fournie par le développeur.

Par la suite, cela se lie au champ ValidityState du champ qui peut ensuite être interrogé pour obtenir des commentaires UX, afin d'éviter une soumission non valide, etc.

Le serveur implémente la même validation de précondition (ainsi que XSRF).

Compte tenu de cela, ce modèle de validation côté client est-il mature et adéquat, ou est-il encore souhaitable pour une raison quelconque d'intercepter le formulaire entier et de le soumettre à la validation traditionnelle par champ avant de le soumettre?

23
msanford

Du point de vue de la sécurité, vous devez revalider tout sur le serveur. Ce sera toujours le cas, peu importe à quel point les fonctionnalités HTML5 sont jolies et avancées. Vous ne pouvez tout simplement pas faire confiance au client. Vous ne savez pas s'il suivra ou non les règles HTML5. Vous ne savez même pas s'il s'agit d'un navigateur.

Devriez-vous donc valider l'ensemble du formulaire avec votre propre côté client JS avant de le soumettre, même si vous utilisez les fonctionnalités HTML5? Du point de vue de la sécurité, cela n'a pas d'importance. La validation côté client n'a de toute façon aucune valeur de sécurité - voir ci-dessus - donc du point de vue de la sécurité, vous pourriez tout aussi bien ne pas vous embêter à le faire.

La validation côté client concerne uniquement l'expérience utilisateur. Si votre propre validation JS ou HTML5 intégrée fait le meilleur UX est une question intéressante, mais ce n'est pas sur le sujet ici.

110
Anders

Une explication avec du code et des captures d'écran

Les réponses données sont excellentes. Mais je voulais illustrer cela avec du code/des captures d'écran.

L'essentiel est que tout ce qui concerne le client peut être manipulé (désactivé/complètement supprimé/contourné ou modifié) par l'utilisateur final. Donc, toute sorte de "validation côté client" est totalement inutile du point de vue de la sécurité. Vous devez toujours valider les choses côté serveur.

Disons que vous avez un formulaire HTML comme celui-ci:

<form method="post" action="index.php">
    <input type="email" name="emailAddress" required>
    <button type="submit">Submit form</button>
</form>

Cela demande une adresse e-mail (type="email"), En disant que c'est un champ obligatoire (attribut required).

Si j'essaie de soumettre quelque chose qui est vide ou pas une adresse e-mail, il y aura une erreur, par exemple.

enter image description here

Pourquoi est-ce inutile du point de vue de la sécurité? Tout ce que l'utilisateur a à faire est de manipuler le HTML. Ils peuvent le faire en enregistrant une copie de la page Web, en la modifiant, puis en la rouvrant. Ou ils peuvent utiliser les outils de développement dans leur navigateur pour modifier le balisage. Ils peuvent le faire car c'est du code côté client, et ils sont sous leur contrôle.

Disons que je change le balisage du formulaire en ceci:

<form method="post" action="index.php">
    <input type="text" name="emailAddress">
    <button type="submit">Submit form</button>
</form>

Je dis maintenant que le champ emailAddress est de type text (c'est-à-dire pas email) et n'est pas un champ obligatoire (attribut required supprimé).

Je peux donc soumettre cela au serveur. La chaîne de texte "andy" n'est évidemment pas une adresse e-mail valide. Mais comme nous n'avons pas (encore) de validation côté serveur, il sera très heureusement publié sur le serveur, puis si le code PHP utilisé $_POST['emailAddress'], Il aurait "andy" comme ses données.

enter image description here

Je pourrais également soumettre le formulaire sans aucune donnée, auquel cas l'application - sans aucune validation côté serveur - aurait une chaîne vide dans la variable $_POST['emailAddress'].

Cela n'était possible que parce qu'en tant qu'utilisateur final, je pouvais manipuler le code côté client.

Pourquoi la validation côté serveur est-elle sécurisée? L'utilisateur final ne peut pas manipuler le code côté serveur (à moins que le serveur n'ait été compromis, mais c'est vraiment un problème distinct et pas quelque chose d'aussi simple que de manipuler le HTML pour la personne moyenne).

Donc, en PHP, je pourrais faire une vérification comme celle-ci:

if (!filter_var($_POST['emailAddress'], FILTER_VALIDATE_EMAIL)) {
    die('Invalid email address');
}

Bien qu'il s'agisse d'une méthode de gestion des erreurs non conviviale, elle arrêtera l'exécution du script si l'utilisateur soumet "andy" au lieu d'une adresse e-mail valide. L'application n'utilisera donc jamais "andy" comme variable dans laquelle elle s'attendait à ce qu'une adresse e-mail se trouve. Étant donné que l'utilisateur final ne peut pas manipuler le code PHP ci-dessus, il y a moins de chances qu'il puisse contourner la validation Il s'agit d'une validation côté serveur - elle ne peut pas (facilement) être modifiée par un utilisateur final car il n'est pas de son ressort de la modifier.

Pourquoi s'embêter avec la validation côté client alors? La validation côté client est utile pour les améliorations de l'interface utilisateur "Nice looking", ou par exemple les messages d'erreur/formulaire de désactivation des champs. Par exemple, c'est sans doute une bonne fonctionnalité d'interface utilisateur pour avoir ce message sur la première capture d'écran au cas où l'utilisateur mal saisir une adresse e-mail. Le formulaire ne sera même pas soumis dans le premier ensemble de conditions, réduisant ainsi les données inutiles envoyées au serveur. Mais finalement, tout ce qui est fait côté client peut être modifié par l'utilisateur final. Il n'est donc en aucun cas sécurisé et vous ne devriez jamais penser à la "validation côté client" en matière de pratiques de sécurité. Toute validation côté client concerne principalement les améliorations de l'interface utilisateur.

La validation côté client est également utile pour les applications côté client (lorsqu'elle ne demande pas/n'est pas publiée sur un serveur). Par exemple, si vous aviez le formulaire donné ci-dessus et que vous aviez ensuite affiché le contenu de emailAddress dans un <div> Sur la page en le lisant avec JavaScript/jquery. Si l'utilisateur saisissait quelque chose comme <script>alert('hello!');</script> et qu'il n'y avait pas de validation, il produirait une alerte lorsque le JavaScript tenterait d'écrire la valeur du champ dans <div>. Dans ce cas, rien n'est publié sur le serveur - tout se passe du côté client -, là encore, la validation côté client est utile dans ce type de scénario. Cependant, la même logique s'applique en ce sens qu'un utilisateur peut toujours désactiver la validation. L'impact ici est moindre car s'ils exécutaient le code ci-dessus, cela ne se produirait que sur leur machine locale, pas pour les autres utilisateurs de l'application. Par exemple:

enter image description here

En utilisant le code suivant (sans aucune validation):

<form method="post" action="#">
    <input type="text" name="emailAddress" id="emailAddress" size="100">
    <button type="submit">Submit form</button>
</form>

<div id="test"></div>

Et jquery pour écrire le contenu du formulaire dans un <div> Avec l'ID test:

$(document).ready(function() {
    $("button").click(function(e) {
        e.preventDefault();

        $("#test").html($("#emailAddress").val());
    });
});
16
Andy

Comme l'a déclaré Anders, la validation côté client n'est pas pertinente pour la sécurité de l'application, mais très importante du point de vue UX.

La validation côté client vise à fournir à l'utilisateur un temps plus fluide et plus facile lors du remplissage de vos formulaires, le meilleur exemple que je connaisse est le plugin jQuery Masks, qui peut être utilisé pour limiter la taille et le modèle d'entrée tout en fournissant un retour visuel à l'utilisateur. Cela peut vous aider sur des failles non liées à la sécurité, comme la réception de données des utilisateurs selon un modèle différent de celui attendu du côté serveur, mais est facilement ignoré par tout attaquant.

tl; dr - Il n'y a rien de tel qu'une validation côté client suffisante, il suffit de ne pas faire confiance au client, il suffit de traiter tout ce qui est reçu sur le serveur avant de le traiter.

6
Bristran

Jusqu'à présent, aucune des réponses ne le mentionne vraiment, alors permettez-moi d'ajouter ceci:

La raison pour laquelle n'importe quoi dans votre code HTML est complètement hors de propos pour la sécurité est que tout attaquant peut, trivialement, créer des requêtes sans même charger de code HTML dans le navigateur (en tapant une requête dans la console, ou en utilisant certains brancher). En fait, sans même démarrer votre navigateur (c/f curl, wget ou tout autre langage de programmation).

La partie pertinente pour ces choses sont les requêtes HTTP . Pas la charge utile HTML. Et à l'exception de la couche TLS/SSL, rien ne protège le contenu de la demande HTTP de la personne réellement création la demande.

Donc, toute sécurité doit avoir lieu côté serveur. Toutes les vérifications côté client sont juste là pour une meilleure expérience utilisateur (sauter un aller-retour).

2
AnoE

Les validations HTML ne s'appliqueront qu'à ceux qui ne savent pas comment changer le code html côté client. Ces validations html peuvent facilement être supprimées et manipulées du côté client. Ayez toujours une validation appropriée sur votre base de données.

0
Harshit Singhal