Storing Credit Card Numbers in SESSION - ways around it? Storing Credit Card Numbers in SESSION - ways around it? mysql mysql

Storing Credit Card Numbers in SESSION - ways around it?


Store the card details to any persistence medium (database, whatever), but encrypt the card number with a unique and random key that you store in the session. That way if the session is lost, the key is too - which gives you enough time to clean out expired/abandoned data.

Also make sure your sessions are protected from hijacking. There are hardware solutions to this, but a simple in-code way is to tie the session ID to a hash of the first octet of the IP plus the user agent. Not foolproof but it helps.

Edit:The key bits to minimizing your risk is to make sure you get rid of that info as soon as possible. Right after the transaction goes through, delete the record from the database. You also need a rolling job (say every 5 minutes) that deletes any records older than your session timeout (usually 20 minutes). Also, if you are using a database for this very temporary data, make sure it is not on an automated backup system.

Again, this solution is not foolproof and I am not even 100% sure it is compliant with CC security requirements. However, it should require an attacker have total runtime control of your environment to actively decrypt customer CC info, and if a snapshot of your database is compromised (much more likely/common), only one CC can be brute-forced at a time, which is about the best you can hope for.


Consider modifying your checkout process to get rid of the necessity of storing credit card information.

Page 1: User enters non-credit-card order information, like shipping and billing address
Page 2: User verifies non-credit-card order information, enters credit card information, and clicks "Pay Now" (or "Revise Order" if they want to change things)
Step 3: Info is submitted via a $_POST request to an SSL page, which completes serverside checks, submits credit card data to processor, and directs the user to a success or error page based on the response.

This way you'll avoid a haze of technical problems and compliance problems. Storing credit card data in a database or cookie, even for a short period of time, even if encrypted, WILL mean that you're responsible for a higher level of PCI compliance. The only tradeoff is you won't be able to show a "review order" page with credit card details. And how big a tradeoff is that, given that your "review order" page can't even show the full credit card number?


I know you mentioned you're aware of PCI compliance, but using any of the methods already described (eg persisting the card number to disc anywhere) will fall foul of PCI and mean you have a nightmare of compliance headaches ahead of you. If you really insist on persisting the card number to disc, then you might as well get a PCI auditor in now to help you through the process and offer advice. Ultimately they will need to validate the method you've taken is appropriate.

As an example, a lot of the answers here talk about using encryption. Thats the easy bit. They haven't talked about key management which is significantly harder

I think therefore a better approach would be to submit the card details to the payment gateway as soon as they are collected. A good many of payment gateways will allow you to perform a 'store only' style transaction, which will perform basic validation of card details and store the card number to their (already PCI compliant) server, and return you a token id instead. This method means you DONT store the full card number/cvv2 anywhere on your servers, and PCI compliance becomes a huge amount easier.

Later in the checkout process you use the token id to submit an authorisation and settlement.

PCI allows you to store the first six/last four digits (and expiry date) of the cardnumber in plaintext, so you can safely capture those wherever you're comfortable with so that they can be redisplayed just prior to the final step.