19 replies [Last post]
Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422

This is a general announcement to anyone out there staying up to date with our commits to Bazaar. I have just committed a fatty patch that totally rearranges the CC settings form and adds in quite a bit of help text to make sure users get started on the right foot.

I also have added a GPL encryption class to core to start encrypting CC data. To that end, anyone updating to this Bazaar version should be sure to run update.php before enabling encryption. To enable encryption, you need to adjust a single setting in your CC settings. Refer to the settings instructions for more information.

DO NOT TRY THIS ON A LIVE SITE. Yet. Smiling I highly recommend testing this on a dev server first, as I had to include a special function to handle folks turning encryption on after already having CC data in the database. There is potential for you to lose CC data when you make the update, and I don't want that to screw up anyone's site.

So now the optimal CC settings for processing cards on your site will be to enable encryption, process cards at checkout, and don't store CC data after checkout. Card details for in checkout orders get wiped after the same amount of time as anonymous carts (added this a while back but forgot about it). This means the only time CC data will be stored on your site will be carts that get abandoned in checkout with valid numbers, but that will all be encrypted and then wiped after the normal anonymous cart interval passes.

Let me know if anyone turns up any bugs!

Once this is confirmed as working, I'll release it as beta 3.

FYI, the encryption class is called uc_encryption_class (easy, eh?) and is defined in uc_store.module so other modules can use it. I'll be using it in uc_recurring.module.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: CC encryption in Bazaar, needs testing

Killer! Thanks for looking into this and working it into the system. I know this is a huge issue and of indescribable importance, especially with identity theft and credit card fraud being out there. Having decent protection, and being able to tell your customers that you've done everything you can to make sure their information is secure, is a trademark of having a mature shopping cart system. Kudos!

--
Help directly fund development: Donate via PayPal!

bmagistro's picture
Offline
Getting busy with the Ubercode.
Joined: 09/24/2007
Juice: 199
Re: CC encryption in Bazaar, needs testing

I am working on a new site and want to enable this off the bat, when I try to enter the path i want that is still in my user directory but not in my web folder i get "You have specified a non-existent directory."

Any thoughts before I go looking through code?

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: CC encryption in Bazaar, needs testing

bmagistro: I would use a full local path to the folder, and make sure you have chmod 775 that folder.

Ryan, here's my only concern. The encryption works great but, when I look in the database, it looks like the encrypted strings are the same length as the unencrypted version. For example, "Visa" comes up as N(cx and "Mastercard" comes up as GZ`OB4.Lo7 (these are not the real unencrypted strings). Notice that the second string is 10 characters, the same length as the word "Mastercard".

I'm not a security, encryption or cryptology expert, but it seems like if I gave someone who was a 4-letter string and they knew that it was a "Card type".. it's not difficult to figure out which card type is which. It seems reasonable enough that a person with enough resources, computing power, and time on their hands (and they are out there) would be able to figure out the encryption scheme from at least those two examples.

I might be making something out of nothing, but I think the encryption should be stronger than that. Dummy characters or something... Just my two cents, of course.

--
Help directly fund development: Donate via PayPal!

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Re: Re: CC encryption in Bazaar, needs testing

Thus, the exception. Yeah, in the encryption, I had to decide what to make different lengths. Personally, I don't think you can get much from knowing what type of card someone has. I know anyone else in Louisville w/ a 5/3 Bank account will have a Mastercard debit/check card, but I can't really do anything with that I don't have a way to restrict what someone puts in that textfield, so I didn't bother mashing it up to some custom string... so yeah, encryption on the card type field is fairly worthless as is.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Re: CC encryption in Bazaar, needs testing

That makes sense. Maybe make it optional to encrypt the card type, or not encrypt that field at all? I just think it's best to keep as few ways of "matching up" encrypted strings to their unencrypted counterparts, the better Smiling

--
Help directly fund development: Donate via PayPal!

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Re: Re: Re: Re: CC encryption in Bazaar, needs testing

Ahh, agreed. Perhaps I'll just go ahead and extend its width to 64 and figure that no one will ever really run into conflicts.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Re: Re: Re: CC encryption in Bazaar, needs testing

Cool, thanks. I'm still working things out on my end but I'll get to more testing. Thanks for listening to the issue.. you can never be too paranoid when it comes to protecting your customers! (well okay, maybe you can.. Eye-wink)

--
Help directly fund development: Donate via PayPal!

lostcarpark's picture
Offline
Joined: 09/22/2007
Juice: 109
Re: CC encryption in Bazaar, needs testing

Just enabled CC encryption in Beta 3, and it's working great. Thanks!

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Re: CC encryption in Bazaar, needs testing

Awesome. Thanks for letting me know. Cool

TR
TR's picture
Online
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3369
Re: Re: Re: CC encryption in Bazaar, needs testing

Sorry about jumping into this thread so late. When it was first posted, the above link to the "GPL encryption class" was broken, so I couldn't evaluate the algorithm. Then I forgot about it until I saw a related post this morning (http://www.ubercart.org/forum/development/3591/ubercart_and_credit_card_...). I've now read up on it and I'm not real comfortable with what I see.

Bottom line: The current encryption method is extremely weak and should be replaced as soon as possible with strong public-key method.

(Ryan, I realize that this post sounds a little critical, but the criticism isn't aimed at you. Protection of credit card numbers is an important issue, and you've taken the time to address it in Ubercart, which is great. And as far as I can tell Ubercart handles the issue at least as well as any other open source e-Commerce solution. So please read the following as a condemnation of the algorthm, and not of you.)

Ubercart uses http://www.tonymarston.co.uk/php-mysql/encryption.html as the basis for its credit card encryption. That URL describes a keyed polyalphabetic substitution cipher, similar to the Vigenère cipher which was first created in the 16th century and was used frequently by the South during the American Civil War. (Interesting historical note: Charles Babbage was the first person to figure out how to break this cipher, sometime in the mid 1800's). These types of ciphers can be quickly cracked with a computer since a frequency analysis will determine the key length and a dictionary search or even simple combinatorics will yield the key. (Lengthening the key past 16 characters - the length of a credit card number - will not help). Likewise, if you have even one piece of plaintext to compare to the ciphertext (e.g. you place an order with a known credit card number), the key can be recovered almost trivially. Compounding this is the regularity of credit card numbers: The first digit is known, there are only 10 symbols (0-9) used in the number, and the checksum built into the number restricts the possible combinations. Also, the more encrypted credit cards numbers you have the easier it becomes to recover the key.

Frankly, given the availability of extremely strong open source encryption algorithms, there is IMO no good reason to use the current method. I think I understand why it was chosen - the Drupal GPL requirement and the availability of a PHP implementation - but these are poor criteria. The only thing that matters is, can the encryption method adequately protect the credit card numbers? For the current scheme, I have to say no.

That said, now that the encryption framework is in place, it's probably easy to plug in a new algorithm. I wish I had time to tackle this myself, but TCS, in his post referenced above, seems to have a solution almost ready to go - I think this should be examined and folded into core right away!

<tr>.
TCS
TCS's picture
Offline
Getting busy with the Ubercode.
Joined: 09/12/2007
Juice: 55
TR, Yes, as I see it, the

TR,

Yes, as I see it, the way to go is asymmetric encryption with the decrypting being done "offline". This adds the complication of installing a small desktop app (and the user having to paste the encrypted info into it while processing each order). I think it is worth it for some clients who are very concerned about security. The standard algorithm is RSA with the keys being sufficiently big (1024 bits). The encryption exponent should not be too small as well (mine uses 65537, the largest known fermat prime, which is a common recommendation). If anybody sees another method that is easier for the cart owner, I would be very interested in getting a discussion started. My current approach might not be optimal.

Cheers

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Re: CC encryption in Bazaar, needs testing

Brilliant post, TR, and I concur fully. I'm glad that encryption has been integrated into UC, but I agree that the method of encryption should be as strong as possible.

Those historical points you made were also quite interesting - thanks for including that.

--
Help directly fund development: Donate via PayPal!

cdeverapalli's picture
Offline
Joined: 03/09/2008
Juice: 6
Help

Hi Ryan, I am wanting to test out the encryption module on a test site I have. I have the beta 3 installed and running drupal 5.7.x and php 4 and mysql4.1.

I have created a directory under / called "uberencrypt" and owner is nobody and CHMOD is 777

Under the Card number encryption key filepath: I am entering "/uberencrypt"

and I get the following error message.

* warning: is_dir(): Stat failed for /uberencrypt (errno=13 - Permission denied) in /var/www/html/hsvworkshop/sites/all/modules/ubercart/payment/uc_credit/uc_credit.module on line 570.
* You have specified a non-existent directory.

I tested it out lifting a few lines from the uc_credit.module as follows:

<?php
$dir
= rtrim('/uberencrypt', '/\\');
echo
"$dir";

   if (!

is_dir($dir)) {
    echo
'You have specified a non-existent directory.';
}

else {
  echo

'Good';
}
?>

and it returns 'Good'. I am running that snippet as root though.

Any advice on what I am doing wrong. I did test it out with beta5 also and got the same but saw on these post where someone got it to work with beta3.

thanks,
Chakri.

bobwm's picture
Offline
Joined: 06/03/2008
Juice: 6
Re: Help

I am new to ubercart.org and have been reviewing the code from a security point of view.

My question is, why are you not using the built-in MySQL functions for cc data?

AES_ENCRYPT()
AES_DECRYPT()

These functions are easy to implement and use a proven algorithm. The passphrase can be stored in a file below the server root to improve security.

These functions will protect against hackers reading cc info after gaining database access through backups or SQL injection.

GPG is even stronger because it doesn't require a passphrase stored on the server, it is a little harder to implement but worth it IMHO.

I apologize if I am missing something obvious but I had to ask.

Regards,

Bob

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Re: Help

Hey Bob, I'm glad you're digging right into the security of Ubercart even as a newcomer. More eyes are a good thing. Smiling

In response to your question, the main reason is I didn't know those existed. I suppose now that I do, a second reason would be questions of compatibility. For example, can these functions be used in a shared hosting environment, do they work uniformly on all recent versions of MySQL, and is there a Postgres equivalent? We don't officially support Postgres, but we've been including contributed support from community users who use Postgres themselves.

I'd appreciate any insights you have.

bobwm's picture
Offline
Joined: 06/03/2008
Juice: 6
Ryan wrote:Hey Bob, I'm glad
Ryan wrote:

Hey Bob, I'm glad you're digging right into the security of Ubercart even as a newcomer. More eyes are a good thing. Smiling

In response to your question, the main reason is I didn't know those existed. I suppose now that I do, a second reason would be questions of compatibility. For example, can these functions be used in a shared hosting environment, do they work uniformly on all recent versions of MySQL, and is there a Postgres equivalent? We don't officially support Postgres, but we've been including contributed support from community users who use Postgres themselves.

I'd appreciate any insights you have.

Ryan,

I'll try to answer....

The functions work fine in shared hosting, in fact encrypting is more important there to protect your database against users on the same box.

AES_DECRYPT() and AES_ENCRYPT() have been MySQL functions since 4.x and they are still in ver 6.0 so I don't think they are going away. The docs don't mention any compatibility issues and I haven't seen any in my limited tested.

The MySQL docs are here:

http://dev.mysql.com/doc/refman/4.1/en/encryption-functions.html

I don't work in Postgres so I can't answer your question about that.

In implementing this protecting the passphrase is crucial. I suggest putting the passphrase in a text file out of the server's path (say ~/password.txt) and chmod it so only the store owner can read/write it. Then you can read the file into a variable as needed to encrypt and decrypt.

Note that the encrypted cc column type must be VARBINARY or BLOB, not STRING

A more secure option is to use GPG (open source PGP clone) to encrypt the data. Because this doesn't require storing a passphrase on the server it even protects you against a malicious root user. The downside is that GPG is a little harder to implement and doesn't integrate directly with MySQL.

I hope this helps,

Bob

bobwm's picture
Offline
Joined: 06/03/2008
Juice: 6
Postgres functions
Ryan wrote:

== Snipped ==

and is there a Postgres equivalent? We don't officially support Postgres, but we've been including contributed support from community users who use Postgres themselves.

Ryan,

I did a little more digging & it looks like Postgres has similar functions:

http://www.postgresql.org/docs/8.3/static/pgcrypto.html

encrypt(data, 'fooz', 'aes')

It's interesting that Postgres has native PGP support along with AES, that appears to put it ahead of MySQL at first glance.

I haven't tested any of the Postgres functions but I hope this helps,

Bob

Ryan's picture
Offline
Joined: 08/07/2007
Juice: 15422
Re: Postgres functions

Thanks for investigating it further. Perhaps what needs to happen is the encryption routine should be a little more open so that modules can provide alternate encryption methods. I'd be open to replacing the core method, too.

I wish this had been an earlier feature so we could've got more ideas like this, but it's definitely on my to-do list for the 2.0 version. Patches welcome. Smiling

bmagistro's picture
Offline
Getting busy with the Ubercode.
Joined: 09/24/2007
Juice: 199
Re: CC encryption in Bazaar, needs testing

I like the idea of using aes, but that is something to consider since pgsql seems to be gaining some ground out there. What about doing the aes encryption in php and then just passing the value to the database commands?