2009-12-22 15 views
9

J'ai un processus de commande pour un panier qui stocke actuellement des données de carte de crédit dans la session pour la récupération une fois que l'utilisateur finalise l'achat. Le processus d'achat est configuré de sorte que l'utilisateur saisisse la carte de crédit, visualise une page de confirmation, puis finalise la commande. Les actions de confirmation et de finalisation sont les deux seules actions qui nécessitent un accès aux données de la carte de crédit et, pour être sûres, toutes les autres actions doivent être rejetées. À moins de faire une réflexion dans un contrôleur de base pour vérifier l'action en cours que l'utilisateur appelle, je ne peux pas imaginer une façon élégante de rejeter les données sur les requêtes non autorisées. De plus, si l'utilisateur ne parvient pas à faire une autre demande après avoir saisi les données, il restera dans la session jusqu'à ce qu'il revienne sur le site Web - chaque fois que cela se produit. Une suggestion m'a été proposée crypter les données dans un champ caché et en s'appuyant sur le ticket SSL pour empêcher la mise en cache du balisage. Cela semble être une approche relativement sûre, mais je n'aime pas beaucoup l'idée de placer les données de la carte de crédit dans un emplacement accessible par l'utilisateur crypté ou non. Le stockage dans la base de données est désactivé car le client ne souhaite pas que les données de carte de crédit soient enregistrées.ASP.NET MVC - Stockage temporaire sécurisé des données de carte de crédit

Quelle est l'approche idéale pour la persistance temporaire de données sensibles comme les informations de carte de crédit pour plus d'une demande de page?


Peut-être que quelqu'un peut me dire si c'est une approche suffisante. J'ai mis mon panier qui est stocké dans la session pour avoir un Guid unique généré chaque fois que l'objet est nouveau et que Guid est utilisé comme une clé pour crypter et décrypter les données de carte de crédit que je suis en série avec le Rijndael algorithm. Les données de la carte cryptée sont ensuite transmises à l'utilisateur dans un champ caché et désérialisées après avoir cliqué sur finalize. Le résultat final est une chaîne beaucoup plus comme ceci:

VREZ%2bWRPsfxhNuOMVUBnWpE%2f0AaX4hPgppO4hHpCvvwt%2fMQu0hxqA%2fCJO%2faOEi%2bX3n9%2fP923mVestb7r8%2bjkSVZDVccd2AJzCr6ak7bbZg8%3d 

public static string EncryptQueryString(object queryString, Guid encryptionKey) 
{ 
    try 
    { 
     byte[] key = Encoding.UTF8.GetBytes(ShortGuid.Encode(encryptionKey).Truncate(16));//must be 16 chars 
     var rijndael = new RijndaelManaged 
          { 
           BlockSize = 128, 
           IV = key, 
           KeySize = 128, 
           Key = key 
          }; 

     ICryptoTransform transform = rijndael.CreateEncryptor(); 

     using (var ms = new MemoryStream()) 
     { 
      using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write)) 
      { 
       byte[] buffer = Encoding.UTF8.GetBytes(queryString.ToString()); 

       cs.Write(buffer, 0, buffer.Length); 
       cs.FlushFinalBlock(); 
       cs.Close(); 
      } 
      ms.Close(); 
      return HttpUtility.UrlEncode(Convert.ToBase64String(ms.ToArray())); 
     } 
    } 
    catch 
    { 
     return null; 
    } 
} 
+0

En ce qui concerne votre mise à jour: Crypter les informations de la carte n'est pas l'obstacle - s'assurer que toutes les pièces de la solution sont sécurisées est difficile. Par exemple, où stockez-vous le GUID utilisé comme clé? Est-ce que quelqu'un d'autre a accès au serveur qui génère les GUID? (Cela peut permettre à quelqu'un de deviner les GUID). Utilisez-vous le même GUID par session ou par durée de vie de l'application? – meklarian

+0

En outre, le bloc catch {} est un peu effrayant. Ne serait-il pas mieux de retourner une chaîne vide là-bas? – meklarian

+0

Bon point sur le ToString() meklarian. Je l'ai copié d'ailleurs sans regarder de trop près. Le Guid est généré une fois par utilisateur par session, donc obtenir un Guid d'un utilisateur serait assez difficile, je pense. –

Répondre

10

La meilleure façon de gérer ce scénario est d'utiliser un service de paiement qui prend en charge deux choses:

  1. Autorisation -> sémantique d'achèvement.
  2. Tokenisation

autorisation vous permet de réserver le montant de charge désigné au moment où les informations de paiement est reçu, puis la fin, vous permet de valider la charge au lot de paiement une fois confirmé le paiement/commande. Si la commande est annulée, vous n'êtes pas obligé d'émettre un Achèvement et vous pouvez également tenter de supprimer l'autorisation. En ce qui concerne la segmentation, la plupart des passerelles qui prennent en charge la méthode susmentionnée de gestion des paiements renvoient un jeton, généralement un identifiant numérique, pour la transaction en attente.Le jeton peut alors être géré comme vous le souhaitez, car il n'a aucune valeur pour quiconque sans avoir accès à vos informations d'authentification au niveau de la passerelle. Cela transfère également la charge de la sécurité à la passerelle.

Le stockage des informations de carte de crédit réelles d'une manière autre que le relais d'une charge à une passerelle/processeur est une mauvaise idée. Au-delà des problèmes de sécurisation des données, votre application sera également incluse dans le périmètre de stockage des informations de carte PCI/PABP, ce qui implique de nombreuses règles et réglementations que vous ne voudrez pas traiter dans votre application. Je crois qu'il y a aussi des frais réglementaires qui seront imposés l'année prochaine pour les demandes conformes, réputées 10 000 $ US. Tout cela ne vaut probablement pas la peine pour vous ou votre client. Enfin, lors du traitement intermédiaire (gestionnaires de page/d'événement/d'itinéraire), vous pouvez utiliser un SecureString pour conserver le contenu des données jusqu'à ce que vous n'en ayez plus besoin.

SecureString class (System.Security) @ MSDN

2

Qu'en est-il en utilisant TempData? Vous devez replacer la valeur dans TempData entre les actions de confirmation et de finalisation, mais au moins, elle sera annulée à chaque requête. Notez que TempData utilise la Session pour le stockage, donc il n'est plus sécurisé pendant qu'il est stocké, mais il a la fonction de suppression automatique. Moi aussi, je résisterais à stocker le numéro sur la page. Je soupçonne que cela viole les règles PCI. Une autre solution consisterait à stocker les informations de la carte dans une base de données. Si vous le conservez dans votre application, vous êtes probablement déjà soumis aux règles PCI. Le stocker dans la base de données le rend plus facile car il suffit alors de mettre l'identifiant de la carte de facturation dans les demandes suivantes. Cela pourrait facilement être dans un champ caché.

+0

J'ai cru comprendre que TempData ne stockait que les données lors des redirections. Si je le mets dans mon Contrôleur, servez une Action, puis traitez une requête pour une seconde action. TempData est parti par ce point que je pensais? –

+0

TempData est stocké entre deux demandes dans la même session. Il est préférable de l'utiliser pour les redirections, mais il n'y a aucune restriction technique. Le framework ne saura pas qu'une requête entrante est le résultat d'une redirection ou d'une autre action. – tvanfosson

+0

Si c'est le cas, cela semble être une approche propre. –

0

Quel est ce pays fondé et ce que les entreprises carte de crédit sont impliqués? Toute l'approche consistant à renvoyer les numéros de carte de crédit complets au client (sous quelque forme que ce soit) donne l'impression que vous n'avez pas traité de carte de crédit professionnelle (ne prenez pas ceci comme une insulte).

Votre client est-il prêt à enfreindre les règles collectives de Visa/MasterCard/AMC/Discover pour le traitement des cartes de crédit en ligne (PCI DSS)? Votre client pourrait être empêché par les principales sociétés de cartes de crédit de faire des transactions avec eux. En général, c'est une très mauvaise idée d'essayer de rouler votre propre solution de gestion de cartes de crédit en ligne - c'est pire que de rouler votre propre algorithme cryptographique, car il peut y avoir de sérieuses amendes sur votre client. Une véritable solution PCI DSS nécessite des dizaines de milliers de dollars en certifications et audits pour garantir le traitement sécurisé des données de carte de crédit - c'est pourquoi presque tout le monde utilise un processeur en ligne existant.

+0

Aucune infraction prise, vous avez absolument raison. Le client est aux États-Unis.Évidemment, nous ne voulons pas avoir à nous soucier de respecter la norme PCI DSS, stocker des données n'est donc pas idéal. –

+0

Le moyen le plus simple d'éviter de stocker des numéros de carte est d'utiliser une page payante hébergée et de laisser le fournisseur s'inquiéter de la gestion des informations de la carte. – tvanfosson

+0

meklarian couvre les spécificités de l'utilisation d'un processeur en ligne existant - en général, plus vous payez, plus les processeurs permettent une personnalisation pour que leur page apparaisse transparente avec le reste de votre site. – David