HTML hidden : valeurs envoyées, modifications JavaScript et limites de sécurité

input type="hidden" inclut un nom et une valeur dans un formulaire sans afficher de champ de saisie. name est le nom de champ soumis et value est sa valeur. Les utilisateurs peuvent l’inspecter ou le modifier, il ne faut donc pas l’utiliser pour protéger les mots de passe, les permissions, les prix ou d’autres décisions sensibles.

Quand faut-il utiliser des entrées cachées ?

Utilisez-le pour envoyer l'ID du message cible avec un formulaire d'édition, ou pour transmettre les conditions de recherche à la requête suivante. Il transmet des valeurs que l'utilisateur n'a pas besoin de taper, tandis que le serveur reste responsable de décider si elles sont valides.

Recevoir un ID de message ne donne pas la permission de modifier ce message. Le serveur doit identifier l'utilisateur via la session authentifiée et vérifier l'accès au message. Ne faites pas confiance uniquement aux informations de compte ou à l'adresse IP du client parce que le client les a envoyées dans des champs masqués.

Type Comportement à l'écran Données du formulaire
type="hidden" Il n'y a pas d'interface de saisie et il ne reçoit pas le focus. Inclus si nommé et non désactivé.
disabled Désactive le contrôle. Exclu.
Entrée ordinaire cachée avec CSS display: none Le CSS cache l'entrée ordinaire de la mise en page. Le fait de cacher uniquement avec le CSS ne l'exclut pas de la soumission.

id peut localiser un élément dans un script mais ne remplace pas son nom soumis. Une entrée cachée sans nom n'est pas incluse comme entrée nom/valeur dans la soumission ordinaire d'un formulaire. Même avec l’attribut required, les entrées cachées ne participent pas à la validation des contraintes du navigateur.

Vérifiez que les valeurs invisibles sont soumises

Enregistrez ce code complet sous le nom hidden.html et ouvrez-le dans un navigateur. Aucun serveur n'est nécessaire. La soumission affiche les entrées nom/valeur créées avec FormData plutôt que de faire une requête réseau.

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Vérifier les valeurs cachées</title>
  <style>
    body { margin: 24px; font-family: sans-serif; }
    label { display: block; margin: 12px 0; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Choisir les couleurs</h1>
  <form id="demo">
    <label><input type="checkbox" name="color" value="blue" checked> Bleu</label>
    <label><input type="checkbox" name="color" value="red"> Rouge</label>
    <input type="hidden" id="size" name="size" value="big">
    <input type="hidden" name="excluded" value="not-sent" disabled>
    <button type="submit">Afficher les valeurs envoyées</button>
    <button type="button" id="change">Passer la valeur cachée à small</button>
    <button type="button" id="restore">Rétablir la valeur cachée à big</button>
  </form>
  <p id="status" aria-live="polite">La valeur cachée initiale est big.</p>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.querySelector('#demo');
    const size = document.querySelector('#size');
    const result = document.querySelector('#result');
    const status = document.querySelector('#status');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify([...new FormData(form).entries()], null, 2);
    });
    function setSize(value) {
      size.value = value;
      status.textContent = `Valeur cachée actuelle : ${value}. Affichez à nouveau les valeurs envoyées.`;
    }
    document.querySelector('#change').addEventListener('click', () => setSize('small'));
    document.querySelector('#restore').addEventListener('click', () => setSize('big'));
  </script>
</body>
</html>
  1. Soumettez initialement : color=blue et size=big apparaissent. Il n'y a pas de case de taille visible, mais sa valeur est incluse. excluded est omis car il est désactivé.
  2. Sélectionnez Rouge et soumettez à nouveau pour obtenir bleu et rouge sous le nom de couleur répété. Décochez les deux cases et seule la taille reste.
  3. Appuyez sur le bouton qui change la valeur cachée en small et soumettez à nouveau : size=small apparaît. Les valeurs cachées peuvent également être modifiées via JavaScript.
  4. Rétablissez big avec le bouton de restauration et envoyez de nouveau. Le bouton de modification sert à observer cet exemple et n’est pas nécessaire dans chaque service réel.

Envoyez le formulaire à un serveur réel

Pour un service réel, définissez l’action sur une route de traitement existante et choisissez une méthode prise en charge comme method="post". Le gestionnaire de soumission de l’exemple bloque les requêtes ; supprimez-le ou remplacez-le par un code de requête serveur pour envoyer les données. Les fonctionnalités de traitement des formulaires côté serveur reçoivent les champs cachés comme des champs de texte ordinaires.

Lors de la réception de plusieurs cases à cocher portant le même nom, vérifiez les règles de tableau et de valeurs multiples du framework serveur. Certains parseurs lisent seulement la dernière valeur répétée. La sortie JavaScript préserve les noms répétés afin que vous puissiez observer la différence.

Ne confondez pas la dissimulation avec la sécurité

Les valeurs cachées sont visibles dans le code source HTML, les outils de développement et les requêtes réseau. HTTPS ne cache pas la valeur à l'utilisateur qui l'envoie. Lors de la réception d'un identifiant de produit, consultez le produit et le prix sur le serveur et validez les valeurs de taille autorisées par rapport aux informations fiables du serveur.

Un champ caché peut contenir un jeton CSRF (Cross-Site Request Forgery). La protection vient d'une émission et d'une validation appropriées du jeton côté serveur. Mettre une chaîne fixe arbitraire dans un champ caché ne prévient pas, en soi, les requêtes forgées.

La référence MDN pour les input cachés explique son comportement et son exclusion de la validation.