web-dev-qa-db-fra.com

Génération et sécurisation de codes de cartes cadeaux

Je travaille pour une entreprise qui génère des codes de cartes-cadeaux qui peuvent être utilisés pour payer des marchandises sur des magasins en ligne.

Je me demande quel est le moyen le plus sûr de générer ces codes de cartes-cadeaux. La longueur doit être de 16 caractères (bien que cela soit négociable) et peut être alphanumérique (bien que le numérique soit plus convivial pour le client).

D'après ce que je peux voir, le moyen le plus sûr de le faire est de générer un code de carte-cadeau d'une longueur spécifique avec le code Java Java:

static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static SecureRandom rnd = new SecureRandom();

String randomString( int len ){
   StringBuilder sb = new StringBuilder( len );
   for( int i = 0; i < len; i++ ) 
      sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
   return sb.toString();
}

Ceci est tiré de la réponse Stack Overflow ici . J'ai supprimé les lettres minuscules de la chaîne pour la rendre plus conviviale. Cela produit donc 36 ^ 16 combinaisons. Numérique seul serait 10 ^ 16 combinaisons. Je pense que le seul chiffre serait suffisant, mais il est souvent souligné que, compte tenu de la prévalence croissante de la fraude par carte-cadeau, la chaîne doit être alphanumérique. Voilà donc la première question: numérique ou alphanumérique?

Lorsque les utilisateurs utilisent les cartes-cadeaux d'une boutique en ligne pour payer des marchandises, un appel est effectué vers notre API qui retourne le solde et la devise de cette carte-cadeau. Étant donné que les codes des cartes-cadeaux sont saisis sur des serveurs tiers, ces cartes-cadeaux sont désormais disponibles pour les personnes ayant accès à ces serveurs. C'est évidemment un problème dans le cas où il reste un solde après qu'un utilisateur en a partiellement remboursé un.

Une option serait de, lorsque l'appel à notre API est effectué (avec le code de la carte cadeau) pour obtenir le solde, nous retournons et enregistrons sur leur boutique une chaîne aléatoire qui ne peut être utilisée par la boutique en ligne que lorsqu'ils nous facturent - nous associerons cela au code de la carte cadeau sur notre système. Le problème avec cela est probablement le code de la carte cadeau que l'utilisateur entre lors du paiement est enregistré quelque part dans leurs journaux et est accessible à toute personne ayant accès à ces journaux.

Une autre option consiste à actualiser le code de la carte-cadeau après son utilisation partielle. Ainsi, l'utilisateur obtient essentiellement un nouveau code de carte-cadeau pour le solde et le précédent est annulé. C'est probablement le plus sûr, mais pas très convivial. Voilà donc la deuxième question: comment sécuriser les codes de cartes-cadeaux qui ne sont que partiellement échangés et qui ont encore de la valeur?

MODIFIER:

Nous avons également une page Vérifier le solde où un utilisateur entre un code de carte-cadeau et la devise et le solde sont retournés. Cela crée probablement des problèmes de sécurité supplémentaires.

12
Mark

Pour éviter la fraude, vous avez besoin d'une probabilité suffisamment faible pour que l'attaquant devine tout code valide. Pour 1 million de cartes, un code 10 ^ 16 sera deviné en moyenne chaque 10 ^ 10 tentatives. Si votre site est complètement sécurisé et que votre API est résistante à la force brute, le numérique devrait suffire à garder cette approche de la fraude non rentable.

Mais c'est une sécurité très fragile, et la protection de hachage ci-dessous sera facile à craquer dans une fuite de base de données avec un si petit espace de clé. IOW, un attaquant ayant accès à votre base de données sera capable de forcer brutalement un grand nombre de codes valides. Un code alphanumérique fournira une sécurité plus robuste. Vous pouvez également faire des compromis en utilisant un modèle de convivialité.

Étant donné que dans votre système, le code est à la fois un identifiant et un mot de passe, pour réduire leurs fuites, vous devez modifier le protocole de communication pour éliminer la transmission et le stockage des codes en clair.

Le protocole le plus simple serait de stocker Salt1 et SaltHash1 = hash (Code + Salt1), puis de transmettre Salt1 au client, de créer Salt2 chez le client, de générer du hash (hash (Code + Salt1) + Salt2) côté client et de vérifier contre le hachage (SaltHash1 + Salt2).

Cela reste vulnérable si votre base de données est compromise, car l'attaquant n'a vraiment besoin que d'une liste de SaltHash1 valide pour effectuer des achats via votre API. C'est aussi lent car vous devez hacher tous les codes valides pour en vérifier un.

Pour le rendre plus robuste, vous pouvez plutôt transformer tous les codes avec un PBKDF comme Argon2id, qui est une fonction lente et irréversible, et ne stocker que le résultat. L'utilisation d'une fonction lente garantit qu'un attaquant avec une base de données divulguée ne peut pas facilement forcer brutalement tous les codes 10 ^ 16 pour trouver tout ce qui convient et simuler un utilisateur légitime. Vous devez toujours faire confiance aux magasins pour ne pas stocker le code et appliquer les connexions HSTS (https uniquement).

Il est impossible de sécuriser ce système contre un magasin escroc qui enregistre les entrées des utilisateurs - s'ils ont le code complet, ils par définition propre la carte. La seule défense est de n'autoriser l'échange de code que via un formulaire chargé directement depuis votre serveur (il peut être intégré dans une page tierce). Si vous faites cela, personne d'autre que l'utilisateur et votre PBKDF ne voient jamais le code; le magasin obtient juste votre réponse de validation.

8
ZOMVID-20

Étant donné que les codes des cartes-cadeaux sont saisis sur des serveurs tiers, ces cartes-cadeaux sont désormais disponibles pour les personnes ayant accès à ces serveurs.

Il est vrai que les administrateurs du serveur peuvent accéder aux cartes-cadeaux, mais ils peuvent également accéder aux numéros de carte de crédit que les utilisateurs entrent dans les magasins en ligne. Si vous pouvez faire confiance à une boutique en ligne pour collecter un numéro de carte de crédit sans faire quoi que ce soit de néfaste, pourquoi ne pouvez-vous pas également leur faire confiance pour collecter un identifiant de carte-cadeau? (Ou peut-être que vous pensez que lorsqu'un administrateur vole des numéros CC, ce n'est pas votre problème, mais s'ils volent des codes de carte-cadeau, c'est votre problème ...).

Votre idée de changer le code de la carte-cadeau après chaque achat devrait fonctionner, mais comment dire à l'utilisateur quel est son nouveau code? Vous pouvez peut-être leur envoyer un e-mail pour les informer de la transaction, inclure leur solde restant et leur fournir un lien pour se connecter et obtenir leur nouveau numéro de carte-cadeau. Je suis d'accord cependant, cela pourrait être quelque peu ennuyeux pour certains utilisateurs. Cela dépendrait vraiment de la fiabilité du commerçant et de l'utilisateur le mieux connu. Peut-être pourriez-vous permettre à l'utilisateur de décider s'il souhaite activer l'option de réinitialisation, et peut-être même lui permettre de définir un seuil au-dessus duquel cela se produit (disons 50 $ par exemple).

1
TTT

Je crois qu'il y a un problème fondamental que vous ne pouvez pas résoudre techniquement. La plupart des mesures antifraude établies réduisent le risque, mais vous devez accepter que la fraude se produira.

Il s'agit fondamentalement d'un problème de confiance. Vous faites confiance aux magasins pour débiter le montant correct de la carte-cadeau pour chaque transaction et pour publier uniquement les transactions autorisées par l'utilisateur. Vous êtes également convaincu que l'utilisateur gardera la carte secrète.

Les problèmes de confiance nécessitent un audit. Comme pour les cartes de crédit, il existe un risque d'utilisation abusive par des tiers. De nombreuses règles PCI DSS concernant les cartes de crédit sont conçues pour minimiser le risque de fraude, mais même avec ces règles, l'industrie des cartes de crédit est confrontée à un risque de fraude substantiel. Pour faire face à ce risque, la banque surveille les signes de fraude et des relevés sont disponibles pour les titulaires de carte afin qu'ils puissent également examiner l'activité du compte pour les transactions non autorisées. Vous ne pouvez pas éliminer le risque de fraude, vous devez donc surveiller et signaler l'activité --- et permettre aux utilisateurs de faire de même .

La vigilance et la réactivité sont les seules solutions à long terme. Malgré des mesures de sécurité raisonnables, vous ne pouvez pas empêcher complètement la fraude. Si cela était possible, l'industrie des cartes de crédit économiserait des milliards de dollars par an. Ils ne pouvaient pas le faire, et votre entreprise ne le fera probablement pas non plus. Votre entreprise et les utilisateurs doivent surveiller les abus et prendre des mesures correctives si nécessaire. Si votre entreprise émet des cartes-cadeaux, elle doit s'engager dans une dotation anti-fraude pendant toute la durée du programme. Même si vous ne poursuivez pas de procédure judiciaire, vous devrez fournir un recours à vos utilisateurs. Quelqu'un doit être autorisé à enquêter et à juger les réclamations pour fraude.

Il existe des mesures de sécurité établies que vous pouvez mettre en place. La plupart des cartes-cadeaux commencent avec un solde nul et/ou elles sont inactives jusqu'à leur vente. Le numéro de compte ou CVV doit être caché jusqu'à ce qu'il soit vendu (soit scellé dans un emballage inviolable ou derrière une rayure). Au point de vente, l'activation est basée sur un numéro de série plutôt que sur l'ID de la carte cadeau --- et l'ID de la carte cadeau n'est pas dérivé de ce numéro de série de manière discernable, ou vice versa.

Les secrets sont partagés, et cela brise la plupart des sécurités. Avec les cartes-cadeaux et les cartes de crédit traditionnelles, les utilisateurs fournissent aux vendeurs tiers tout ce qui est nécessaire pour se faire passer pour eux. C'est un contraste frappant avec les systèmes basés sur la blockchain qui permettent aux utilisateurs de garder leurs secrets confidentiels. Lorsque vous avez affaire à un système fondamentalement peu sûr, vous devez mettre en place des contrôles compensatoires ou des atténuations de ces risques. Ensuite, vous acceptez tout risque qui reste et continuez.

1
DoubleD

Dans le monde des cartes de crédit, chaque transaction en ligne où un client saisit son numéro de carte dans un navigateur nécessite le numéro de carte ET le code CVV2. Il s'agit généralement d'un code à 3 chiffres imprimé au dos de la carte. Les commerçants sont invités à NE JAMAIS stocker ce numéro, mais peuvent conserver le numéro de carte (sous des restrictions très strictes).

L'analogie est que le numéro de carte est comme un nom d'utilisateur, tandis que le CVV2 est comme le mot de passe (en quelque sorte, peut-être!). Votre problème semble être que vous ne comptez que sur les numéros de carte, ce qui revient à ne compter sur les noms d'utilisateur que pour des raisons de sécurité. C'est un problème, il devrait y avoir un moyen d'authentifier la carte, le numéro de carte n'est qu'un identifiant.

Ma suggestion est d'ajouter une sorte de PIN à la transaction. Le client doit fournir le PIN dans l'appel d'API avant qu'il puisse être approuvé. Ce PIN ne doit jamais être stocké dans les journaux des commerçants. Si cela vous inquiète, essayez de créer un code PIN unique (OTP) que vous envoyez au client lors d'une transaction, mais cela ajoute un tas de complexité, mais supprime également le risque de réutilisation des commerçants la carte pour une autre transaction - car ils n'auront jamais l'OTP.

Changer le numéro de carte est une chose encore plus difficile à faire - et probablement pas le meilleur parcours client, je ne le conseillerais pas.

1
keithRozario

J'ai parcouru toutes les réponses et trouvé une solution, en tenant compte des suggestions:

  • Nous générons un lien à envoyer à l'utilisateur. La clé envoyée dans le lien est une chaîne alphanumérique aléatoire et elle est hachée (MD5 ou quelque chose de similaire), elle ne peut donc pas être inversée avant d'être enregistrée dans la base de données.

  • Lorsque l'utilisateur clique sur le lien, il est redirigé vers notre page de destination, nous utilisons la clé pour obtenir la commande, vérifions le statut de la commande et s'il y a du crédit dessus, et si ça va nous générons un code alphanumérique de 16 caractères et envoyer à l'interface utilisateur. Le code à 16 caractères est haché (à nouveau MD5) et enregistré dans notre base de données. Chaque fois qu'un utilisateur clique sur le lien, il voit un nouveau code de carte cadeau tel qu'il est généré à la volée à chaque fois.

  • Dans le contrat avec la boutique en ligne, nous précisons qu'ils ne peuvent pas enregistrer ou enregistrer le code de la carte cadeau n'importe où (nos 2 clients sont de grands détaillants en ligne bien connus)

  • Sur la page de paiement de la boutique en ligne de notre client, pour payer avec notre code de carte-cadeau, l'utilisateur fournit le code de carte-cadeau à 16 caractères. Il est envoyé à nos serveurs et le solde et un ID de paiement aléatoire est retourné à la boutique en ligne. Ce numéro de paiement est enregistré sur la boutique en ligne dans le cadre de la commande. Une fois la commande terminée, la boutique en ligne envoie une demande d'API (avec le paiement ID) à nos serveurs pour racheter le montant de la carte-cadeau (cette fonctionnalité a été construite par nous et est fournie à la boutique en ligne via un plugin qu'ils installent).

  • la communication entre la boutique en ligne et notre API est authentifiée à l'aide de OAuth 2.0

  • S'il reste un solde sur la carte cadeau, un nouveau code de carte cadeau est généré (l'utilisateur reçoit un nouveau lien pour obtenir son nouveau code de carte cadeau pour le solde)

  • Lorsque la boutique en ligne nous facture, ils nous fournissent une liste des ID de paiement, que nous associons ensuite aux codes des cartes-cadeaux dans notre backend (puis appariés à notre émetteur).

Protège:

  • Le code de la carte cadeau n'est pas envoyé à un e-mail - juste le lien (dans notre backend, nous pouvons faire quelques vérifications - comme voir la commande a expiré, le crédit a-t-il déjà été utilisé, avant d'afficher le code de la carte cadeau)

  • Une personne ayant accès à la base de données de la boutique en ligne ne verra pas nos codes de carte-cadeau

  • Une personne qui a piraté notre base de données ne peut pas voir les codes de carte-cadeau (car ils sont hachés), ni générer le lien pour voir les codes de carte-cadeau (car la clé du lien est hachée)

Faites-moi savoir s'il y a des commentaires.

0
Mark