Formulaires : contourner l'attribut disabled
Sur certains sites, des formulaires sont visuellement verrouillés via l’attribut HTML disabled, sans qu’aucune vérification ne soit faite côté serveur. Retirer cet attribut depuis les outils de développement du navigateur suffit à soumettre le formulaire.
Le problème
Section titled “Le problème”L’attribut disabled est une directive purement côté client. Il indique au navigateur de griser le champ et d’empêcher l’interaction, mais il n’envoie aucune information au serveur et ne constitue pas un mécanisme de contrôle d’accès.
Un exemple typique de formulaire mal protégé :
<form action="" method="post" name="authform"> <div> <input disabled="" type="text" name="login" value=""> <input disabled="" type="submit" value="Access" name="authbutton"> </div></form>Si le serveur ne vérifie pas que l’utilisateur a le droit de soumettre ce formulaire (abonnement actif, rôle, session valide…), retirer disabled et soumettre la requête suffit à contourner la restriction.
Exploitation
Section titled “Exploitation”Via les DevTools du navigateur
Section titled “Via les DevTools du navigateur”- Ouvrir les outils de développement (
F12ou clic droit → Inspecter) - Localiser le champ ou le bouton portant
disabled - Double-cliquer sur l’attribut dans le panneau HTML et le supprimer
- Soumettre le formulaire
<!-- Avant --><input disabled="" type="submit" value="Access" name="authbutton">
<!-- Après modification dans les DevTools --><input type="submit" value="Access" name="authbutton">Via la console JavaScript
Section titled “Via la console JavaScript”Pour retirer disabled sur tous les champs du formulaire en une ligne :
document.querySelectorAll('[disabled]').forEach(el => el.removeAttribute('disabled'));Via une requête directe
Section titled “Via une requête directe”Si l’endpoint est connu, contourner entièrement le formulaire et envoyer la requête POST directement :
curl -X POST https://exemple.com/auth -d "login=test&authbutton=Access"Si le serveur traite la requête sans vérification d’autorisation, la restriction est contournée.
Ce que ça révèle
Section titled “Ce que ça révèle”Ce type de protection côté client indique souvent que :
- aucune vérification d’autorisation n’existe côté serveur pour cet endpoint
- la restriction repose uniquement sur ce que l’interface présente à l’utilisateur
- d’autres formulaires ou boutons sur le site peuvent être protégés de la même façon
Une fois un formulaire déverrouillé, tester systématiquement les autres champs cachés ou désactivés sur le même domaine.
Remédiation
Section titled “Remédiation”L’attribut disabled peut rester présent pour l’expérience utilisateur, mais il ne doit jamais être le seul mécanisme de contrôle.
Côté serveur, vérifier à chaque requête :
// Exemple Spring Security@PreAuthorize("hasRole('SUBSCRIBER')")@PostMapping("/auth")public ResponseEntity<?> auth(@RequestBody AuthRequest request) { // traitement du formulaire}La règle : toute restriction visible dans l’interface doit être appliquée côté serveur, indépendamment de ce que le client envoie.
À retenir
Section titled “À retenir”L’interface utilisateur n’est pas une frontière de sécurité. Tout ce qui s’exécute dans le navigateur — HTML, JavaScript, CSS — est modifiable par l’utilisateur. Un contrôle d’accès qui repose uniquement sur disabled, hidden, ou une classe CSS n’en est pas un.