0

I have a form, with some sensitive info (CC numbers). My work flow is:

  • One page to take all form items
  • Upon submission, values are validated. If all is well, all data is stored in a session variable, and the page reloads and displays this info from the session variable.
  • If everything is ok on the review page, the user clicks submit and the session variable is sent to another form for processing (sending payment).
  • Upon success, the session is destroyed. Upon failure (bad CC number, for example) - the user is sent back to the form, with all of the fields filled in just like before, so that they can check for errors and try again (session is NOT destroyed).

Does anyone see anything wrong with this, from a security or best practices stand point?

UPDATE I'm thinking I can get rid of a step - storing the info in a session EVER. Just have a one page checkout, no review page... makes sense.

Martin.
  • 10,494
  • 3
  • 42
  • 68
Shackrock
  • 4,601
  • 10
  • 48
  • 74
  • Do **NOT** store the CC number in the session, especially in the clear. If you're storing it on your server, **YOU** are responsible for its security and it **MUST** be stored securely. Writing it to a sesion is NOT secure. – Marc B Nov 13 '11 at 17:15
  • @marcb I'm not Storing for more than a few minutes (long enough for the user to submit the form). And if they don't finish the process (submit the final form) - when the session times out, then the variable is gone... isn't it true that I do NOT need encryption then? – Shackrock Nov 13 '11 at 17:23
  • Go ahead and try to leave your physical credit card on a bar counter or somethinf for a few minutes while you go hit the washroom. I'm sure it'll be fine. PCI standards exist for a reason, and if you violate them (by storing a CC in-the-clear, even for a very short interval), you're in for a world of hurt down the road. – Marc B Nov 14 '11 at 00:55
  • @MarcB Yea, I updated the post: `UPDATE I'm thinking I can get rid of a step - storing the info in a session EVER. Just have a one page checkout, no review page... makes sense.` - so there is zero storage now. – Shackrock Nov 14 '11 at 01:30

4 Answers4

1

I believe the CC number has to be encrypted. You may want to search for PCI compliance. There are some topics that cover the security aspects here on StackOverflow.

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

Community
  • 1
  • 1
koen
  • 13,349
  • 10
  • 46
  • 51
  • That solution says to store the CC number to a temp DB - which is the same as storing in a temp session, in my opinion. Right? The only difference is the encryption of the number, which I'll need to look into. – Shackrock Nov 13 '11 at 17:27
  • @Shackrock I'm not pointing to that solution but rather to security concerns that come up with your question that are addressed in a similar topic. A quick search on SO reveals there is interesting info about the security concerns in handling cc numbers. – koen Nov 13 '11 at 17:47
0

some small points

  1. there are some validation routines you can do in JS before submitting the form - check length of credit card numbers, check that date is in the future, do some vlidation on the number itself (Luhn algorithm)

  2. if there is an error, don't fill out all form entries. leave the credit card and security number empty.

  3. the credit card number input box should have a random HTML name, so someone one with access to the computer can't simply reload the page and have the browser autofill the credit-card field

Kae Verens
  • 4,076
  • 3
  • 21
  • 41
  • 1. Yep, actually I'm doing that, just some added checks in PHP. 2. Also true, CC and CCV are not saved in this case. 3. I use `autocomplete="off"` in the html, so the browser will not try to auto fill. – Shackrock Nov 13 '11 at 17:26
0

Add some hash (signature) to form with IP address and client browser, and display CC code from $_POST only if signature is correct.

Failure form (pseudocode):

$sig = md5($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] . $_POST['cc_code']);

<input type="hidden" name="sig" value="'.$sig.'" />
CC: <input type="text" name="cc_code" value="'.($sig==$_POST['sig'] ? $_POST['sig'] : '').'" />

But IMO the best option is leave fields with CC code empty.

Peter
  • 16,453
  • 8
  • 51
  • 77
0

As someone that's gone through PCI compliance several times, I can honestly tell you, it's a steaming load of BS.

The best practice is to offload the storage of the credit card data onto a large service provider that has already dealt with PCI compliance and, in all honesty, has more resources, experience and credibility in the marketplace.

I'm talking about someone like http://www.braintreepayments.com/

Credit card data is a hot potatoe. You want to get that stuff off of your server asap, but still have access to use it for recurring billing.

Hope that helps...

Homer6
  • 15,034
  • 11
  • 61
  • 81