Le court code imprimé sur une carte de paiement est le champ sur lequel les gens hésitent lorsqu’ils lisent une carte à voix haute, et cette hésitation est tout l’intérêt. Un CVV est un secret distinct qui ne vit que sur le plastique, pas dans le numéro, pas dans la date d’expiration, et dans rien qu’un voleur pourrait reconstituer à partir d’un reçu. Il a été ajouté parce que les paiements sans présence de la carte avaient besoin d’un indice que la personne saisissant les détails avait réellement la carte en main.
Cet article explique ce qu’est le code, pourquoi sa longueur change d’un réseau à l’autre, pourquoi les règles de paiement interdisent de le conserver, et ce qu’il faut surveiller lorsque vous construisez ou testez un formulaire qui en demande un.
Ce qu’est le code de sécurité et où il est imprimé
Pour la plupart des réseaux, le code est composé de trois chiffres imprimés au dos de la carte, soit à l’intérieur de la bande de signature, soit juste à côté. American Express place quatre chiffres au recto, au-dessus du dernier groupe du numéro de carte.
La valeur est générée par l’émetteur lors de la fabrication de la carte. Elle n’est pas dérivée du numéro de carte, ce n’est pas une somme de contrôle, et elle ne peut être calculée à partir de rien d’autre d’imprimé sur la carte. Si vous perdez le code, vous ne pouvez pas le retrouver par arithmétique ; l’émetteur doit réémettre la carte.
La documentation utilise plusieurs noms pour le désigner, et la numérotation de ces noms est significative plutôt que décorative. Le terme simple décrit des données encodées dans la piste magnétique ou la puce, tandis que la version numérotée deux est la valeur imprimée qu’un client lit à voix haute. Un test d’un terminal avec présence de carte et un test d’une page de paiement touchent donc des champs différents, même si les noms semblent interchangeables.
| Famille de réseau | Longueur du code | Où il est imprimé |
|---|---|---|
| Visa, Mastercard, Discover, UnionPay | Trois chiffres | Dos de la carte |
| American Express | Quatre chiffres | Recto de la carte |
Pourquoi le code compte-t-il trois chiffres sur certaines cartes et quatre sur d’autres ?
La différence vient du plan de numérotation choisi par chaque réseau, et non d’une distinction de sécurité. Un code à quatre chiffres n’est pas plus robuste qu’un code à trois chiffres dans un sens significatif ; les deux sont assez courts pour que la devinette ne soit pas le modèle de menace. La longueur fait simplement partie de la spécification du réseau, de la même manière que ses numéros de carte utilisent un nombre de chiffres différent.
Pour quiconque construit un formulaire, ce simple fait engendre la plupart des bugs de ce domaine. Un champ codé en dur sur trois caractères tronque un code American Express sans le dire à l’utilisateur, et un validateur qui exige trois chiffres rejette une carte légitime. L’approche pragmatique consiste à demander d’abord la marque à l’utilisateur, ou à la détecter à partir du numéro, puis à dimensionner le champ en conséquence — avec une borne supérieure qui refuse malgré tout une saisie absurde.
Que prouve le code, et que ne prouve-t-il pas ?
Dans une transaction sans présence de la carte, le commerçant ne peut pas voir la carte, donc le système de paiement demande quelque chose qu’une personne la détenant peut lire. Le numéro et la date d’expiration auraient pu être recopiés d’une ancienne facture ou d’une base de données divulguée ; le code imprimé ne l’aurait pas pu, car il n’a jamais été écrit ailleurs.
Cela en fait un obstacle modeste mais réel à la fraude occasionnelle, et c’est pourquoi le champ n’est pas décoratif. Les réseaux traitent le code comme la preuve qu’une transaction a satisfait un niveau de vérification plus élevé, et les commerçants qui le collectent correctement sont traités différemment de ceux qui ne le font pas lorsqu’une fraude est contestée. Les termes précis de ce transfert de responsabilité appartiennent aux réseaux ; pour quiconque construit un formulaire, la conclusion pratique est simplement que le champ doit être collecté, et non simulé.
Ce que le code ne prouve pas, c’est que la carte est authentique ou que le compte est en règle. Une valeur devinée de la bonne forme passe instantanément tout contrôle côté client, car un formulaire n’a aucun moyen de vérifier un secret qu’il ne peut pas voir. Seule une demande d’autorisation auprès de l’émetteur peut répondre à cette question.
Pourquoi les règles des cartes interdisent-elles de stocker le code ?
C’est la règle qui surprend le plus les équipes techniques. Selon la norme de sécurité des données de l’industrie des cartes, le code de sécurité est classé comme donnée d’authentification sensible. Il peut être utilisé pour autoriser une transaction, et il ne doit pas être conservé après l’autorisation — ni dans une colonne de base de données, ni dans un fichier de journal, ni dans un tableur, ni dans un message sur une file qu’un processus consomme dix secondes plus tard.
Le raisonnement est simple. Un code stocké est un identifiant de paiement stocké. Si une violation expose des numéros de carte, l’attaquant a encore besoin de quelque chose de plus pour les utiliser en ligne ; si elle expose les codes en même temps, les numéros deviennent immédiatement utilisables.
En revue, les manquements ressemblent rarement à des choix délibérés :
- Une colonne ajoutée à la table des commandes pour une session de débogage et jamais supprimée.
- Un intergiciel de journalisation des requêtes qui enregistre tout le corps soumis, code compris, dans un agrégateur aux contrôles d’accès plus faibles que le système de paiement.
- Un rapporteur d’erreurs qui joint la charge utile du formulaire en échec à chaque exception.
- Une file de réessai qui garde intacte la requête de débit d’origine afin de pouvoir la rejouer.
Chacun est un manquement à la conformité, et aucun ne ressemble à cela au moment où il est écrit.
Remplir un champ de code de sécurité sans erreur
L’essentiel de la difficulté ici relève de la saisie plutôt que de la sécurité, et les cas délicats sont assez prévisibles pour être anticipés :
- Un code plus long que le champ. Quelqu’un colle quatre chiffres dans une case de trois caractères. Soit vous tronquez discrètement, soit vous affichez un message, mais choisissez un comportement et appliquez-le de manière cohérente.
- Une saisie non numérique. Des lettres, un espace, un tiret issu d’un bloc copié. Le champ devrait les refuser sans effacer ce que l’utilisateur a déjà tapé.
- Les zéros initiaux. Un code commençant par zéro est légal et ne doit pas être normalisé en interprétant la valeur comme un nombre.
- Le masquage. Cacher les chiffres au fil de la frappe semble rassurant, mais vérifiez que cela ne casse pas le remplissage automatique ni ne pousse le navigateur à traiter tout le paiement comme un écran de connexion.
- Les claviers mobiles. Un pavé numérique est plus rapide à utiliser, ce qui compte pour un champ que l’on remplit en tenant la carte dans l’autre main.
Pour les développeurs : garder le code hors des journaux et du stockage
La discipline d’ingénierie ici est une soustraction. Le traitement le plus sûr d’une donnée d’authentification sensible est de ne pas l’avoir dans un système à un autre moment que celui de l’autorisation.
Commencez par examiner ce que votre couche de journalisation capture réellement. Un framework qui journalise les corps de requête par défaut enregistrera le code, et la destination des journaux est souvent un service tiers aux règles d’accès différentes. Si le code n’atteint jamais votre serveur — parce qu’un champ de paiement hébergé le collecte directement — le problème disparaît, et c’est l’option la plus solide disponible.
Là où vous manipulez la valeur, traitez-la comme transitoire. Ne l’ajoutez pas à un objet de modèle qui sera sérialisé dans une ligne d’audit, ne l’incluez pas dans une charge utile de réessai, et ne laissez pas un gestionnaire d’exception l’attacher à un rapport. Écrivez un test qui parcourt votre sortie de journal après une exécution et échoue si une valeur en forme de code apparaît ; ce seul contrôle attrape la majorité des conservations accidentelles.
Examinez ensuite vos données de test. Tout ce qui remplit le champ automatiquement devrait provenir de valeurs synthétiques, examinées avec le même soin que n’importe quelle autre fixture de paiement. Les notes PCI DSS couvrent les règles plus larges sur ce qui peut vivre dans un environnement de test, et la liste de contrôle du formulaire de paiement situe ce champ dans la séquence des flux à exercer avant le lancement.
Les cartes de test et leurs codes fictifs
Une carte générée a besoin d’un code pour remplir le champ, et cette valeur est fictive de la même manière que le reste de la carte. Elle a la bonne longueur et le bon jeu de caractères, et elle ne correspond à aucun secret détenu par un émetteur.
C’est la façon exacte de décrire tout ce que renvoie le générateur de ce site : des données structurellement valides qui n’ont jamais été émises. Un code fictif fait paraître une démonstration ou un test de préproduction complet, et il n’autorisera rien nulle part.
Étapes suivantes
Vérifiez sur un formulaire que vous possédez trois choses dans l’ordre : si le champ s’adapte à la longueur de code du réseau, si la valeur finit dans un journal ou une table, et si les messages d’erreur distinguent une mauvaise longueur d’un caractère non pris en charge. Pour obtenir un numéro à associer au champ, utilisez le générateur de numéros de carte, et pour la date qui le jouxte, le guide de la date d’expiration couvre les règles de limite.