Les CAPTCHA sont-ils accessibles?

Pourquoi les stratégies habituelles utilisées en ligne ne sont-elles pas accessibles et ne constituent-elles pas une option pour nous? Les CAPTCHA suivants sont généralement utilisés pour prévenir les attaques par un BOT, mais ne sont pas accessibles ou entièrement conformes, et/ou présentent d’autres défis identifiés.

Les CAPTCHA

CAPTCHA fondés sur des images

Non accessibles, car les personnes ayant une déficience visuelle ne peuvent pas voir les images et saisir l’information demandée.

CAPTCHA audio

Fonctionnera avec les lecteurs d’écran, car l’utilisateur peut « entendre » le ou les mots, mais peut être exploité par un robot intelligent et présente le même problème que les CAPTCHA fondés sur des images pour les personnes ayant une déficience visuelle. Voici un article qui traite en détail du CAPTCHA audio (disponible seulment en anglais).

reCAPTCHA

Utilise des mots numérisés, mais présente le même problème que les CAPTCHA fondés sur des images pour les personnes ayant une déficience visuelle.

Solutions de rechange

En plus des CAPTCHA susmentionnés, les éléments suivants sont également utilisés pour prévenir les attaques.

Les noms communs ne sont pas utilisés pour les attributs

Lorsque les robots naviguent sur le Web, ils cherchent habituellement des noms de champ communs comme l’adresse de courriel, le nom, etc. Cette information peut être obscurcie pour décourager les robots, mais cela créerait de la confusion pour nos utilisateurs finaux légitimes. Cette option est accessible, mais elle n’est pas conviviale.

Champs de saisie masqués

Un champ qui n’est pas requis aux fins opérationnelles peut être masqué à l’aide de feuilles de style en cascade, Cascading Style Sheets (CSS). Un BOT remplirait habituellement ce champ caché et lorsqu'il soumettra le formulaire, nous pourrons vérifier si ce champ contient des données, auquel cas nous rejetons simplement la soumission. Cette option est accessible, mais elle peut être piratée.

Question aléatoire

Des questions aléatoires peuvent être posées en fonction des « autres » données saisies par l’utilisateur. Par exemple : Quels sont les deuxième et septième chiffres de votre numéro de téléphone? Cette option est accessible, mais elle peut être piratée et il faut déployer beaucoup d’efforts pour la mettre en œuvre.

Champ d’adresse courriel/processus de confirmation

La saisie d’une adresse courriel et la mise en œuvre d’un processus de confirmation par courriel protègent contre les attaques BOT parce qu’un courriel contenant un lien de confirmation unique est envoyé à l’utilisateur immédiatement après la soumission du formulaire. La confirmation réussie au moyen de ce lien permet de vérifier l’authenticité de l’utilisateur et de conserver les données. Si l’abonnement n’est pas confirmé dans un délai déterminé par l’entreprise, les données sont supprimées. Ainsi, les données enregistrées dans la base de données proviennent d’un utilisateur réel et non d’un BOT, ce qui assure l’intégrité et l’exactitude des données.

Renseignements supplémentaires

Pour sécuriser davantage les données du formulaire, il est recommandé de mettre en œuvre la fonctionnalité additionnelle suivante.

Champs de saisie masqués

Comme on l’a vu, cette option n’est pas entièrement sécurisée en soi, mais lorsqu’elle est utilisée avec le champ d’adresse courriel/processus de confirmation, elle ajoute une couche supplémentaire pour protéger les données et n’est pas difficile à mettre en œuvre. Pour assurer l’accessibilité et la conformité, ce champ sera masqué visuellement, y compris pour les lecteurs d’écran, et la valeur d’entrée de ce champ sera vérifiée avant d’accepter les données.

Recommandation

Il est recommandé de mettre en œuvre les méthodes suivantes pour le formulaire Web afin d’optimiser l’expérience et l’accessibilité des utilisateurs et d’assurer l’intégrité et l’exactitude des données :

Pour en savoir plus sur les CAPTCHA et d’autres méthodes pour prévenir les attaques par un BOT, nous vous encourageons à visiter la page Captcha Alternative and thoughts (disponible seulment en anglais) sur le site Web du W3C.

Technique Honeypot

Préambule

Fonctionnement de la technique Honeypot :

  • Il s’agit d’exposer un champ de formulaire à un robot, mais pas à un humain.
  • Le champ doit avoir un but pouvant être déterminé par un programme informatique, comme en utilisant un élément label associé à l’input afin qu’un robot puisse déterminer ce qui est demandé.
  • Ce champ devrait être quelque chose que l'on pourrait demander dans le formulaire, mais qui ne l’est pas, comme une date de naissance ou un numéro de téléphone secondaire.
  • Un robot devrait avoir autant d’indices que possible pour que le champ puisse être rempli, par exemple en ajoutant « required » au texte de l'élément label; il ne faut pas enchâsser un nom de classe comme « hidden » ou style="display:none;".
  • Ajoutez les attributs required à l’<input>, puis demandez au navigateur de ne pas en tenir compte, soit en les supprimant avec JavaScript juste avant la soumission du formulaire, soit en utilisant l’attribut novalidate de l’élément <form>.
  • Pour éviter que les humains le remplissent :
    • Il doit être masqué visuellement (comme utiliser class="sr-only", class="wb-inv").
    • Il doit être retiré de l’ordre des onglets en utilisant tabindex="-1".
    • Ils doivent être cachés des lecteurs d’écran en utilisant JavaScript pour appliquer aria-hidden="true" sur un élément parent de input et de label.
  • Si, après la soumission, le serveur détecte une valeur dans le champ du formulaire, il doit ignorer la soumission du formulaire.

Exemple de code

Le code suivant est le strict minimum nécessaire pour que cela fonctionne. Il s’agit d’un formulaire d’inscription au site Web qui nécessite un nom d’utilisateur, un mot de passe (à saisir deux fois) et une adresse courriel. Le champ Date de naissance est un champ Honeypot.

HTML


<form id="regForm" action="registrationPage" method="POST" novalidate>
<div>
	<label for="username"></label>
	<input id="username" name="username" aria-describedby="formatforusername" required />
</div>
<div>
	<label for="password"></label>
	<input id="password" name="password" required type="password" />
</div>
<div>
	<label for="repassword"></label>
	<input id="repassword" name="repassword" required type="password" />
</div>
<div>
	<label for="email"></label>
	<input id="email" name="email" required type="email" />
</div>
<div>
	<label for="birthday" class="invisibleStuff"></label>
	<input id="birthday" name="birthday" class="hpclass" required />
</div>
		
<div>
	<input id="saveBtn" name="saveBtn" value="Register" type="submit" />
</div>
</form>
<script src="user.js">

CSS


.invisibleStuff {
	position: absolute;
	height: 1px;
	width: 1px;
	clip: rect(1px, 1px, 1px, 1px);
	overflow: hidden;
	margin: 0;
}

.hpclass {
	z-index: -5;
	font-size: 0pt;
	position: relative;
	top: -5em;
	height: 0px;
	overflow: hidden;
	width: 0;
	line-height: 0px;
	margin: 0;
	padding: 0;			 
}

Javascript


function hp () {
	let hps = document.querySelectorAll("input.hpclass");
	window["wb-frmvld"] = {"ignore" : "input.hpclass"};  // This line is only necessary if the page uses WET validation

	for (let i = 0; i < hps.length; i++) {
		hps[i].setAttribute("tabindex", "-1");
		hps[i].classList.add("invisibleStuff");
		hps[i].parentNode.setAttribute("aria-hidden", "true");
	}
}
	
document.addEventListener("DOMContentLoaded", hp, false);