38

I am well aware of PCI Compliance so don't need an earful about storing CC numbers (and especially CVV nums) within our company database during checkout process.

However, I want to be safe as possible when handling sensitive consumer information and am curious how to get around passing CC numbers from page to page WITHOUT using SESSION variables if at all possible.

My site is built in this way:

  1. Step 1) collect Credit Card information from customer - when customer hits submit, the information is first run through JS validation, then run through PHP validation, if all passes he moves to step 2.
  2. Step 2) Information is displayed on a review page for customer to make sure the details of their upcoming transaction are shown. Only the first 6 and last 4 of the CC are shown on this page but card type, and exp date are shwon fully. If he clicks proceed,
  3. Step 3) The information is sent to another php page which runs one last validation, sends information through secure payment gateway, and string is returned with details.
  4. Step 4) If all is good and well, the consumer information (personal, not CC) is stored in DB and redirected to a completion page. If anything is bad, he is informed and told to revisit the CC processing page to try again (max of 3 times).

Any suggestions?

EDIT

I have received a lot of really good response on this question - majority seem to agree on the following:

  1. taking POST variables after validation is run
  2. encrypting ccnum and cvv (not sure you are allowed to store cvv in DB at all though)
  3. Storing in temporary DB
  4. Access DB immediately after 'review' page is OK'd
  5. decrypt details from DB
  6. send information to processor
  7. receive response
  8. terminate DB

I think this makes sense overall. Does anybody have good method for the encryption/decryption along with best way to create temp DB info that is automatically deleted on later call?

I am programming in PHP and MySQL DB

EDIT #2

I came across Packet General which seems like an ideal solution but REALLY don't want to pay for another software license to accomplish this goal. http://www.packetgeneral.com/pcigeneralformysql.html

EDIT #3 - Sample Code

I have now posted some example code I put together trying to make sense of the encryption/decryption/key and storage mentioned in this post. Hopefully, the already helpful contributors can validate and others are able to use similar functionality. For the sake of length I will not go into the validation methods used for the actual CC num itself.

Form Input

<form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="text" name="CC" />
<input type="text" name="CVV" />
<input type="text" name="CardType" />
<input type="text" name="NameOnCard" />
<input type="submit" name="submit" value="submit" />
</form>

PHP Encrypt and Storing Data

<?php

$ivs = mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($ivs,MCRYPT_RAND);
$key = "1234"; //not sure what best way to generate this is!
$_SESSION['key'] = $key;

$ccnum = $_POST['CC'];
$cvv = $_POST['CVV'];
$cctype = $_POST['CardType'];
$ccname = $_POST['NameOnCard'];

$enc_cc = mcrypt_encrypt(MCRYPT_DES, $key, $ccnum, MCRYPT_MODE_CBC, $iv);
$enc_cvv = mcrypt_encrypt(MCRYPT_DES, $key, $cvv, MCRYPT_MODE_CBC, $iv);
$enc_cctype = mcrypt_encrypt(MCRYPT_DES, $key, $cctype, MCRYPT_MODE_CBC, $iv);
$enc_ccname = mcrypt_encrypt(MCRYPT_DES, $key, $ccname, MCRYPT_MODE_CBC, $iv);


//if we want to change BIN info to HEXIDECIMAL
// bin2hex($enc_cc)

$conn = mysql_connect("localhost", "username", "password");
mysql_select_db("DBName",$conn);

$enc_cc = mysql_real_escape_string($enc_cc);
$enc_cvv = mysql_real_escape_string($enc_cvv);
$enc_cctype = mysql_real_escape_string($enc_cctype); 
$enc_ccname = mysql_real_escape_string($enc_ccname);

$sql = "INSERT INTO tablename VALUES ('$enc_cc', '$enc_cvv', '$enc_cctype', '$enc_ccname');

$result = mysql_query($sql, $conn) or die(mysql_error());
mysql_close($conn);

Header ("Location: review_page.php");

?>

PHP decrypting data and sending off to gateway

    $conn = mysql_connect("localhost", "username", "password");
    mysql_select_db("DBName",$conn);

$result = mysql_query("SELECT * FROM tablename");

echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_ccnum, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_cvv, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_cctype, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_ccname, MCRYPT_MODE_CBC, $iv);

mysql_close($con);
?>

then proceed to take the data just sent in the string and use in Gateway submission. Seem right?

JM4
  • 6,740
  • 18
  • 77
  • 125
  • Call me crazy, but I think it's easier to save the encrypted CC number in the session. If it doesn't get deleted for whatever reason, it'll disappear when the session expires. – mpen May 24 '10 at 21:22
  • @Mark - MAN YOU SO CRAZY! In all seriousness, is this similar to the threat TC posted below? My understanding is that if a SESSION is hijacked then you now have the key and card number exposed. – JM4 May 24 '10 at 21:26
  • @JM4: Hrm... I guess that depends where you keep the key. I'd use two keys anyway. One hard-coded key, and one key that changes with the client/session. Could be randomly generated for each session, plus based on the user agent (IP addresses supposedly aren't good because they can change due to roaming). That way if the random key is hijacked, they still need access to your code to steal the other key, or if they did that, hopefully they aren't quick enough to nab the random key. – mpen May 24 '10 at 21:42
  • ...either way, I think the idea is to keep the key and the CC number separate. I think there's basically 4 places to store stuff. 1) hard-coded, 2) in the DB, 3) in the session, 4) on the client. 1) can't be changed, so it's only good for saving a constant key. If 3) is compromised, I'd argue that 2) could be coerced into giving up its info, unless you don't have a 3). And 4) should definitely be utilized to ensure you're still talking to the same client and not some hacker that's trying to steal his place. – mpen May 24 '10 at 21:48
  • ...assuming you're running this over SSL and you have secure cookies enabled, you shouldn't be able to hijack the session though, so I don't think 3) is nearly as bad as people make it out to be. Take advantage of all 4 if you can find a way. – mpen May 24 '10 at 21:51
  • don't use
    use
    instead as the first type is sensitive to injection.
    – alexanderpas May 25 '10 at 00:27
  • Session hijacking refers to stealing the session cookie (stored on the client), not the session data (stored on the server). If you steal the session cookie, it doesn't matter where on the server the data is stored. – tc. May 25 '10 at 02:36
  • 1
    Also, please don't use DES. It's been cracked many times. – tc. May 25 '10 at 02:43
  • @tc - thanks for the advice. I was really only using as sample code to show the overall process. Do you have encryption you'd recommend? – JM4 May 25 '10 at 15:34
  • I'd love to know/why this question was downvoted a year after the fact? – JM4 Dec 13 '11 at 22:16

13 Answers13

13

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.

Rex M
  • 142,167
  • 33
  • 283
  • 313
  • That's not how you prevent session hijacking. Usually it'll be provided by whatever framework you're using (e.g. PHP) so there's not much you can do about it anyway. – tc. May 25 '10 at 02:38
  • @tc how do you prevent session hijacking? – Rex M May 25 '10 at 03:16
  • You securely generate a session identifier. Assuming that the web framework you're using is secure, your sessions are secure. If the web framework you're using is not secure, then upgrade to a version that is. Do not write your own session-generation/handling code, you **will** get it wrong the first time. – tc. May 25 '10 at 12:32
  • 1
    @tc how is a session identifier "secure"? It is a string in a cookie, regardless of how securely that string was generated. If I take the value out of your cookie and put it in mine, and the only piece of information the server uses to identify you is the value of the cookie, I have your session. There has to be a second piece of information to validate the cookie value that is also independent of the cookie value. – Rex M May 25 '10 at 15:31
  • @tc - generating "secure" session_ids is just as secure as storing the information in SESSION to begin with. If the ID could not be jacked then the information within the session could not either. Perhaps you know incredible methods of doing this that none of the rest of us do. Judging by your answers on SO, I can see you know what you are talking about for the most part but I dont know if we are on the same page. For reference, I am using basic PHP 5.3.2 for this code (please dont tell me I need to switch to Zend and an MVC framework) – JM4 May 25 '10 at 16:01
  • I did not choose to go this route but felt it was the best answer. I am working directly with our vendor to store the information in a PCI secured vault they actually maintain and working with token system. Thank you so much for your help. Perhaps I will be able to sit down one day and manage this all on our end. – JM4 May 27 '10 at 20:22
  • @JM4. So you went with my answer? Nice :) I may be biased, but I think anyone considering storing credit card numbers would think twice if they went over the PCI requirements. – PaulG May 29 '10 at 08:32
10

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?

Summer
  • 2,488
  • 3
  • 23
  • 32
  • we have discussed just this below but I think it is a good point. After doing some more research, even some of the big companies like Go Daddy don't offer 'review' pages. All pages during the enrollment process are 2048 bit SSL protected by the way (page 1 - page 10) – JM4 May 25 '10 at 15:55
  • This method is the easiest, I think, but prevents using a Post/Redirect/Get form model. – swt83 Jun 26 '10 at 03:22
9

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.

Community
  • 1
  • 1
PaulG
  • 13,871
  • 9
  • 56
  • 78
  • very good answer. I checked with our merchant yesterday morning and am still waiting a response. From what I can tell, they are trying to charge us additional per month and per transaction which is absurd in my opinion but MAY be worth it. – JM4 May 25 '10 at 15:36
  • looking over again, we actually can't show any part of the credit card number or show a confirmation page at all. Doing so would require storing the credit card number in a session during the review process (hence this question) and then posting those variables to the merchant API. We use direct POST variables when sending the information off. – JM4 Jul 06 '10 at 17:43
  • @JM4. I possibly havent explained clearly, but I was suggesting POSTing directly to the gateway as soon as the details are collected, and storing (PCI compliant) the last 4 digits only. The POST to the gateway is (at this point) solely storing the details onto the payment gateway. The confirmation page can then reshow the last four digits and (after confirmed) make another POST to the gateway to perform auth/settlement using the token id (not payment details) returned from the gateway. There are other slightly different approaches you could take also if you still wanted a confirmation page. – PaulG Jul 06 '10 at 20:24
  • Its a fairly common approach to the problem, and is hugely easier than the 'accepted' answer, which will cause PCI headaches – PaulG Jul 06 '10 at 20:26
  • going the route you mention requires significant additional cost to merchants through almost every gateway. In our particular case, there is a $50 monthly charge for the 'customer vault' then an additional $0.25 per transaction which does not justify the means. Thank you for your help though. – JM4 Jul 07 '10 at 20:22
6

Is there any reason you can't skip the confirmation step and just submit the transaction immediately?

I don't see why keeping it in a database is any more secure than keeping it in a session variable — server compromise will still give away the credit card number, but if you keep it in the session it's far less likely to be written to disk. You can encrypt it if you want, but the usefulness of this is dubious (it'll still be swapped to disk). Adding another machine to do encrypted storage doesn't help either, since the compromised machine can just ask the other one to do decrypting.

EDIT: Just thought of this:

  1. Generate a random 128-bit key. Save this in the session.
  2. Encrypt the data with the key. Send it to the client in an <input type="hidden">
  3. On confirmation, decrypt the data and submit the transaction.

An attacker needs to compromise both the client and the server to get the credit card number (such an attacker would probably have the number already anyway). An online server compromise will still get the credit card numbers of future transactions, but you can't really stop that.

EDIT: And I forgot the details. For all of these schemes (not just mine), you also need a MAC to prevent replay attacks (or Eve distracts Alice, modifies the shopping basket and billing address, and hit the "confirm" page...). In general, you want to have a MAC on all the transaction data you have (CC, CVV, transaction ID, transaction amount, billing address...).

tc.
  • 33,468
  • 5
  • 78
  • 96
  • 1
    @tc - I have been tinkering with that idea for awhile now. Being an online customer - I feel it gives the consumer peace of mind then they are entering their payment information to be able to review it all before hitting the final 'submit' button. It is also fairly common practice on every single site out there – JM4 May 24 '10 at 21:03
  • @tc - your edit doesn't really address the goal (store CC and CVV outside of session). Assuming it is the best method though - Are you assuming I generate the key (no clue how to do that), encrypt data, store data and key both into session, then when needed use the same information to decrypt the card? How is this any safer than what I am alrady doing given the key is in SESSION now. If the SESSION is hijacked, now the key and card number are both exposed. – JM4 May 24 '10 at 21:11
  • @JM4: How is the card number exposed? It's no where on the server now, it's sent to the client (encrypted). – mpen May 24 '10 at 21:20
  • @Mark - Perhaps I am misundestanding but what Client are we referring to? The processor? The consumer? – JM4 May 24 '10 at 21:28
  • @JM4: By "client" I mean the person viewing the site. Their computer. – mpen May 24 '10 at 21:38
  • @Mark - so i'd be sending 'encrypted' CC numbers as a cookie to the client machine? Seems like a bad idea – JM4 May 24 '10 at 21:39
  • @JM4 no, the key to decrypt the CC info is on the client. However, this is not really an improvement over storing in session, since either way the decryption info is in-memory on the server for some short period of time. If the server is compromised to the point that the attacker can "listen" for session data coming through, they can also get POST data. – Rex M May 24 '10 at 22:03
  • 1
    @JM4: I thought TC meant to send the CC num back, but yes, it does make more sense to send the key back to the client and then wipe it from the server ASAP. They shouldn't be able to read any of the transmissions if it's running over HTTPS... – mpen May 24 '10 at 22:19
  • @Rex M - that is not what TC states above - "Generate a random 128-bit key. Save this in the session." The key is staying server-side in this example and the CC is being sent back. I truthfully don't like any of the options really just given the horror stories some people post about info being jacked. No 'review' page is ugly but likely the best method (although like you said, POST variables can be stolen anyway so there is no difference here). – JM4 May 24 '10 at 22:44
  • 1
    You should not be writing crypto if you do not know how to generate a key. – tc. May 25 '10 at 02:40
  • @Rex M: The plaintext-equivalent data is **ALWAYS** going to be on the server at some point. There's absolutely nothing you can do to change that. My scheme sends the client (browser/user) something it (he/she) already knows; what's the attack? It's encrypted largely so that someone can't just "view source" to get the number. – tc. May 25 '10 at 02:50
  • @tc that's my point - it's not an improvement, it's just different. – Rex M May 25 '10 at 03:13
  • @tc - trying to learn best practices so advice is much better than telling me not to do something. – JM4 May 25 '10 at 15:44
4

You are right, using sessions is very insecure for storing sensitive data, there are ways to break into sessions with what is know as:

Session hijacking
Session fixation

The most secure way that comes to my mind is that store the info in database (for temporary time) and then read that value on the page where you need it. Once you are finished doing it all, you can delete it back.

Note that:

  • you must encrypt it before saving to database.
  • be careful if you are on shared hosting
  • make sure that you delete it back once done with it

You may find this reflectively useful as well :)

Community
  • 1
  • 1
  • @web logic - thanks for the info, i added new edit. I am also programming in PHP – JM4 May 24 '10 at 20:57
  • 1
    How is the DB more secure than storing it (encrypted) in a session? If they can hijack your session, then your app will be tricked into reading it from the DB just as easily. – mpen May 24 '10 at 20:59
  • 1
    @Mark: I have agreed with him in not using sessions :) I have also asked him to store it encrypted. –  May 24 '10 at 21:01
  • @Web: But he already *is* using sessions to authenticate the user. I'm saying if a hacker steals your session, you're screwed either way (whether you store it in the DB, or in the session). – mpen May 24 '10 at 21:14
  • 1
    @Mark: in his question, his text reads *WITHOUT using SESSION variables if at all possible.* –  May 24 '10 at 21:20
  • 1
    @Mark - I am not authenticating any user at this point. I do not make a single DB call until the end of the enrollment process and by this point have already unset() the CCNum. My goal is to try and eliminate CCNum from SESSION altogether and ONLY use the POST variable from page 1 to 2 – JM4 May 24 '10 at 21:30
  • Oops... I thought you must be using sessions to maintain the state across the pages... but I guess you're right. You could POST it along and use the DB instead then. – mpen May 24 '10 at 21:35
  • @Mark - I will store on page 7 and need to call that same information again on page 9/10 but just want to avoid SESSIONS with all the hijacking possibilities. – JM4 May 24 '10 at 21:40
3

There is another way, but it requires Ajax. No storing of credit card numbers AND a review page.

Page 1: Form to capture shipping, billing and credit card information. Ensure that the "body" of the page, including the form, is in a DIV with a unique ID to allow you reference it with JavaScript.

Page 2: A file on the server that will accept a GET/POST request with the form fields in it and return a properly formatted "review" page to your liking.

Checkout process:

  1. Validate form.
  2. Copy credit card related fields into global JavaScript variables.
  3. Loop through form fields and build a query/data string with the form fields (excluding credit card related fields)
  4. Do an Ajax request to the "review" page, passing the query string of form field/values with it. Render on server and return to calling Ajax function.
  5. Take rendered HTML review page returned from Ajax request and replace content in your "DIV" container with it (effectively replacing the form and other elements with the review HTML).
  6. Use JavaScript to copy the credit card data stored in global JS variables into the appropriate place on the review page. You may also copy the card data to hidden form fields to submit when the user "completes" the order from the "review" page.
  7. User submits order from review page to server, performing card validation with the processor's gateway and then either placing the order, or returning to error handling page, never having stored the card details.
  8. I would recommend that the "place order" function perform a full HTTP request (rather than Ajax) in order to reload the browser with a page that no longer has the card data stored in global JS variables.

It's a bit of a hack, but when done properly, it's 100% seamless to the user and allows you a single transmission of the card data with no need to assume risks with temp DB storing, etc.

Burgertech
  • 31
  • 2
3

It appears that anyway you touch it, you'll need to provide for secure credit card number storage capabilities. If the server is compromised, at any time it will contain enough information to decrypt currently stored credit card numbers (i.e. keys and encrypted numbers). Potential solution is to use an internal server that acts as a "encryptor/decryptor" service and nothing else. This way compromising one machine does not expose credit card numbers.

Greg Adamski
  • 1,099
  • 7
  • 7
2

This is what a database is for. I'm not sure about the legal ramifications here (which vary based on country and region), but one approach would be to encrypt the CC number and store it in the database as soon as you receive it from the user. You may want to store the last 4 digits in a separate field so that you can show it to the user when required. When you need to interact with the card processor on the server, retrieve and decrypt the card number from your database.

3Dave
  • 28,657
  • 18
  • 88
  • 151
  • 2
    PCI compliance is a requirement of your agreement with credit card companies (Visa, Mastercard) - not really the country or region you live in. Unless you're willing to spend a lot of time and effort on compliance, you should not store customer credit card numbers, since doing so automatically moves you into a more stringent set of compliance requirements. – Summer May 24 '10 at 20:59
  • @Summer - we are already forced to become PCI compliant as I said in this first line. I am well aware of the policies and what it takes. I am only trying to find out, technically, best practices for passing information from page to page. – JM4 May 24 '10 at 21:05
  • 1
    It'd be great if whoever voted "-1" would post an explanation. Considering that my suggestion is identical to others (store it somewhere other than the session, and don't pass it back and forth within the browser), I fail to see why this answer was singled out. – 3Dave May 24 '10 at 21:09
  • @David - i assume it was Summer given the comment abotu PCI Compliance for country/regions. Who knows. He/She chose to ignore the very first line in my question anyway so I'll bump you for good measure. – JM4 May 24 '10 at 21:14
  • 2
    Explanation: this answer seems to suggest that you SHOULD store CC numbers in the database, that a two-way encryption process is adequate data security for credit card numbers, and that PCI compliance depends somehow on your country/region. I don't believe any of those three statements are true. I truly didn't mean to offend, just want to make sure the highest-voted answers are the best ones and at the time of the downvote, yours was rated quite highly. – Summer May 25 '10 at 15:17
  • 1
    @Summer Thanks for the clarification. If this is the case, however, how do sites keep card information associated with your account for your next purchase? My bank, New Egg, Amazon, etc all do this. – 3Dave May 25 '10 at 15:55
  • 2
    @EVERYBODY - I would be very interested to know that answer as well. My initial guess is that they have gone through rigorous PCI-DSS Level 1 Compliance reviews and honestly have a staff of people dedicated to that work only. – JM4 May 25 '10 at 16:08
2

Here's how I plan on doing it - everything over https using ssl of course.

Step 1. User enters CC info and presses the next button. The CC info is immediately saved to the CC processor's DB, not your own DB or you'd break PCI Compliance. The CC is not actually charged this step. But you should recieve some unique ID from the processor identifying the CC info. (store the unique id in your db if you want)

Step 2. On the confirmation page, retrieve the CC info from the CC processor using the unique id they gave you. My processor will only let me retrieve the last 4 numbers of the CC anyway.

Step 3. After they confirm the purchase and press the purchase now button, charge the credit card using the unique id.

Step 4. Redirect to a thank you page containing the invoice/reciept which only has the last 4 digits of the CC (Of course you don't have to display the last 4 of the CC, but I think it's a nice thing to show).

goku_da_master
  • 4,257
  • 1
  • 41
  • 43
  • thanks for the info. Your answer assumes though in step 1 the processor has that functionality at all. What processor are you using that allows temporary storage of the CC (also, storing CC does not break PCI Compliance, cvv does). – JM4 Jan 24 '12 at 19:05
  • Authorize.net using the CIM API. – goku_da_master Apr 04 '12 at 23:54
1

You could store a hash of the card nr in session and the same hash and the actual number and the user's session id in a database. Then for each page you can check the hash and the session info to get the card nr.

Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
  • unsure how to go about this entirely - but appreciate info – JM4 May 24 '10 at 21:12
  • 4
    This doesn't make much sense. It sounds like you're advocating storing the CC number in the DB in clear text, then you've sprinkled some hashes around that don't really serve a purpose. – mpen May 24 '10 at 21:54
1

At some point later on in the payment processing (last part of step 3), you'll need to encrypt the CC# (and CVC) to be able to send it to the payment processer (I assume)

Why not do that encryption right when you recieve the information, next to the obfuscation needed for the confirmation page. (this is the last part of step 1)

From now on, only work with this encrypted or obfuscated data, making the CC-company the only one who can actually decrypt the full data.

alexanderpas
  • 2,712
  • 2
  • 23
  • 33
  • there is no way to allow the CC company to decrypt the information as they do not provide unified encryption methods. – JM4 May 25 '10 at 15:56
1

There is no need for sessions or the database to hold the information.

Every page is a form that posts the data. On each subsequent page the post variables from the previous page are added to hidden form fields so that the next form submission posts the data again. This way nothing is ever stored, but the information is carried from page to page. This also forces the user to complete the process from start to finish without attempting to skip steps.

As long as the form is submitted over HTTPS, the data is encrypted automatically and the security burden is on your SSL certificate provider.

Many popular commerce sites implement this. For example OSCommerce.

None
  • 5,491
  • 1
  • 40
  • 51
0

Use Tokenization. Its fully PCI DSS complient.

More can be fouhd here, https://www.pcisecuritystandards.org/documents/Tokenization_Guidelines_Info_Supplement.pdf