Would you consider the use of caching products in the category of data at rest?
Yes. It doesn't matter what the product is, if it stores, processes or transmits payment card data then it is within scope of PCI-DSS.
Having said that, if your cacheing device only stores encrypted data and doesn't have access to any keys used for decryption then you should be able to agree with your QSA that it is out of scope for your assessment.
If it does handle unencrypted payment card data, or if it has access to decryption keys then you will have to implement at least a sub-set of the PCI-DSS controls for the cacheing devices.
This is a complex issue, but anything that is held for over 24 hours is considered as "storage" and is under strict controls about how card data is handled - No CV2 for example.
But you also the data must be on its way to the card transaction and not in the return path after the transaction.
You probably need to discuss your specific example and exactly what use of which bits of card data you are concerned about with your QSA
Agreed this is complex, but based on my understanding, there is a couple of principals you can draw from in PCI-DSS:
Card holder data must be encrypted when being transmitted over an open network. So if you have a local cache and the data from the cache is to be transmitted over an open network, thats an area you will have to address.
Store only what you need. If you dont need some parts of the the card holder data, including CV2, expiry then dont store it even if its being stored in what cant be considered data at rest.
Its seems in my view that if your cache is storing card holder data, its going against the grain of the standard. The intention in relation to data storage (amoungst others) is to limit storage, use, transmission to only where actually required for sensitive data. Without further details from you on your cache content, I cant imagine why you need to cache sensitive data.
I certainly agree with Mr Cheekysoft in that you should be open and discuss with your QSA as I am sure he/she once enlightened on the details will be able to provide you with some guidance.
Related
I am creating a payment processing page for use via stripe and I want to be able to have my customers manages saved cards or use a new one. I am worried about being too forthcoming with some customer information and the possibility of exposing too much card information to my servers.
If I retrieve sensitive info like last 4, exp date, etc. should I be putting some means of encryption on it or is it completely fine to display or store pieces of that information for relationships server side on my end?
EDIT: New dev here be gentle :)
The only PCI-sensitive information is the entire card number and the CVC.
The card's brand, last 4 digits and expiry date are not sensitive. If you use Stripe, you can retrieve this information the card object's attributes, e.g. exp_month and exp_year, etc.
From a PCI compliance point of view, you don't need to do anything special to handle this data since it is not considered sensitive. My recommendation would be to either simply query the information from Stripe as needed, and discard it afterwards, or store it as-is into your database (in that last case, you'll probably want to use webhooks to make sure your DB is synced with your Stripe account).
I see many sites that store cookie data as garbled text, for example: a cookie named aASFaewqWDRE#fr with an equally unreadable value. I've always kept my cookies human readable, but never keep critical data within them. For example, I'd make a cookie called favorite_items with a string like so 14,73,7, each number being a reference to something like a product.
If my cookie were to be stolen, the attacker would immediately know that this user had items 14, 73, and 7 in their favorites. This doesn't compromise the users account in any way, as far as I know (assuming that my site is well built and an account can't be accessed with solely this information).
Are there other security concerns with this practice that I haven't thought of?
How do I really know that this is question is really from the legitimate user Brian? How do I know that it's not someone trying to trip people up? It would be in the general interest of security (for whatever reason) to encode ('garble') your data - simple because you do not know who or what is monitoring your data. Consider an account with amazon or a major retailer where a customer's credit card information is on file. If the data being monitored, it would be very simple for a potential hacker/malicious program to extract the information he needs. He can either directly get credit card details or he simply just has to acquire their username/password combination. Now when this comes to banks, it becomes extremely important.
But even outside of financial transactions, it is good to encrypt your details to prevent you from being spammed and or to prevent the illegal use of your account - imagine your boss getting an email from you with stuff that he might not like. The list is endless. The bottom line really is that there are a lot of messed up people out there and if you can do something to get that extra level of protection for not much additional cost, then why not?
What are the dangers of storing plaintext data in cookies?
The "danger" is obvious. The user (and potentially others!) can read the information, and potentially "fiddle" with it.
Whether it matters depends what the information is, how you handle the cookies and what you are worried about. For example ...
If you are using the cookie content for implementing your site security / user access control, then passing the information it the clear could give the user extra some knowledge to subvert your scheme ... depending on how you implemented it.
If you are using the cookie content for information that the user might consider as sensitive, then passing the "clear" cookies over an HTTP connection makes it vulnerable to some bad guy who can snoop the packets. (Actually, given the HTTPS is "not really as secure as we were lead to believe" ... this probably applies across the board!)
If you are using the cookies for tracking the user ... or something else that the user would probably not like you doing ... well, go figure!
But seriously, your question strongly suggests that you need to learn a lot more about how to address security and privacy concerns in website / webtool implementation.
For a start, simply "garbling" the information is insufficient. Any light-weight "garbling" scheme can easily be reverse engineered. If you care about security / privacy, the information should be encrypted using strong encryption with properly handled keys ... or not stored in cookies in the first place. (Read up on schemes for storing session-related information on the server side.)
Back Story
I work at a small-mid size company and we are reworking our customer facing accounting portal and my manager wants to make single click payment option with the Credit Card info stored in cookies on the end users computer. I'm not in love this the idea.... at all (in fact I'm still trying to change his mind). That being said I am trying to make it as secure as I can, I think I've got a way to minimize the risk, here it is:
using SSL for all exchanges
encrypt the data in a number of cookies that are stored locally
having the cipher as a confirm password that must be entered each time. forcing the cipher to be strong, say 15+ mixed chars, and this is confirmed by checking a hash of it on the server.
I know that the major weak spot is the cookie info that is stored in a two way encryption, that said is this a reasonably safe way to store the info....
The Question
How can it be improved using this basic method.
Please I know that there is going to be a lot DON'T DO IT! answers (if I was not asking, I would be one of them) so please be specific, you are preaching to the choir on this so be constructive in the negatives.
Edit - If you have a specific point that you think I can use in reasoning with my manager please share. (I've already brought up that we maybe legally responsible if the CC info is stolen from a cookie, and he said he would have a lawyer look that over)
Thank you.
using SSL for all exchanges
Should be done no matter what solution you use, as long as credit cards/payment info is involved. As you probably know.
encrypt the data in a number of cookies that are stored locally having
the cipher as a confirm password that must be entered each time.
forcing the cipher to be strong, say 15+ mixed chars, and this is
confirmed by checking a hash of it on the server.
I usually remember my credit card number, and I'd rather put that in (as I'm already intent on not disclosing it to anyone) than a long and complicated key that most customers would write down somewhere anyway.
Even if we aren't allowed to say "don't do it!" - why don't you ask us for good ways to dissuade your manager from taking this decision? ;-)
What makes you unwilling to store this server-side? It's not like Amazon stores my credit card info in a cookie. The basic idea is to store all user info on the server, and access it when a user has authenticated successfully (i.e. logged in).
Cookies are in this case used to persist the logged in-state between browser sessions. The info this logged in-session has access to is stored on the server. With credit card info this usually entails a lot more security than other sensitive info, but it's the same basic idea.
Storing actual credit card numbers in cookies (encrypted or not) could be a potential PR nightmare when some tech-savvy customer realises what you are doing.
Thread for more reading: What information is OK to store in cookies?
Edit: The more I read through this question the more dumbfounded I get. Does your manager even know what a cookie is? How it works? What the point of it is? Saying that you want to store credit card info in cookies is like saying you want to use shoes as a means to transport shoe-laces. He is actively and purposefully shooting himself in the foot for no reason whatsoever. What he wants to achieve can be achieve a lot easier with other, much safer techniques - without any loss in functionality whatsoever.
From an article linked by Scott Hanselman:
Storing Credit Cards
If you absolutely must store credit card data it should be stored in encrypted form.
There are various compliance standards (specifically CSIP and PCI) that vendors are supposed to follow that describe specific rules of how networks need to be secured and data stored. These rules are fairly complex and require very expensive certification. However, these standards are so strict and expensive to get verified for that it's nearly impossible for smaller businesses to comply. While smaller vendors are not likely to be pushed to comply, not complying essentially releases the credit card company of any liability should there be fraud or a security breach. In other words you are fully responsible for the full extent of the damage (realistically you are anyway – I'm only echoing back the rough concepts of these certifications).
(my emphasis)
Point out that Cookies are transmitted across each request. If you store credit card information in them not only is it less safe, but you are not actually gaining any sort of realistic time benefit. Outside of being easier to implement, there is no reason to do it this way. Since you're the one implementing it he shouldn't care about the ease of implementation anyway...
Edit: You could also point out that if anything goes wrong, he will be the one getting fired for it. Threatening his job is a great way to get him to see it your way.
Don't use the user's password as the key, or at least, it shouldn't be the only thing that comprises the key. You should encrypt the credit card account information with a private key that is stored on the server (and not known to the user).
You can decrypt the credit card information on the server, even though it's stored on the client. This way, there is no way for the encrypted credit card information to be reversed on the client (without knowing the private key).
You might encrypt the credit card account information with both the private key and the user's entered password, that way, they can't be sent to the server to be decrypted without the proper password.
Storing credit card information securely and legally is very difficult and should not be attempted. I have no intention of storing credit card data but I'm dying to figure out the following:
My credit card info is being stored on a server some where in the world. This data is (hopefully) not being stored on a merchant's server, but at some point it needs to be stored to verify and charge the account identified by merchant submitted data.
My question is this: if you were tasked with storing credit card data what encryption strategy would you use to secure the data on-disk? From what I can tell submitted credit card info is being checked more or less in real time. I doubt that any encryption key used to secure the data is being entered manually, so decryption is being done on the fly, which implies that the keys themselves are being stored on-disk. How would you secure your data and your keys in an automated system like this?
If I was storing the number, I would be a giant service provider with a massive database. That database is spread across a highly-redundant storage array consisting of multiple cabinets, in separate rooms or ideally in separate geographical locations, connected by a SAN. My biggest insider threat is the distributed physical plant, the constant stream of worn-out drives, and several daily shifts of technicians, administrators, and engineers. It's a huge threat.
Therefore I would encrypt the data on a physically-isolated computer that connects to the mass storage over a network. The software would be as simple as possible: encryption and number verification. The public interfaces and business logic goes elsewhere. Accesses would be logged to a separate SAN.
Encrypt with something like AES. The raw AES key is only ever stored in RAM. The key is wrapped in a PGP file for each administrator, who has their own passphrase to enable the server. Less-trusted personnel can be given partial passphrases to use in disaster recovery, or passphrases can be stored in a vault somewhere. For encryption, pick a unique initialization vector (IV) for each card number, AES-encrypt the number using that IV, and store the IV and encrypted number to the SAN. Decryption only occurs using a privileged client interface; normal client connections used for purchases can never get a decryption.
For vendors to process and store your credit card info, they generally have to get PCI certified. The requirements should be outlined here. Some of the requirements are very straightforward, and others are vague and open to interpretation. Going through the process is not fun, and a company having the certification doesn't mean your data is safe.
But it's better than nothing I suppose.
It's quite easy to store a salted hash of a credit card number rather than the number itself for secure lookups. For 99% of the scenarios out there, this would be sufficient credit card for storage -- fast and very secure.
If you really need reversible encryption of a credit card for some scenario (continued billing, for example), I would go with a symmetric key stored in a secure location other than the database. It's been a while since I looked at PCI specs, but I'm fairly certain that's PCI compliant.
If you need fast lookups along with reversible encryption, use both options: a hash and an encryption.
Edit:
There seems to be some controversy over my answer. I would like to point out the following very interesting essay from Integrity.com (PDF):
Hashing Credit Card Numbers: Unsafe Application Practices
It details many of the issues involved in storing a hash of credit card data, but its conclusion confirms my suggestion.
Yes, a raw hash of the card is not secure; that's why we salt our hashes! But a static salt is also not secure, they allow the creation of rainbow tables for known static salts. So it's best to make our salts vary in some way that is unpredictable. In the case of passwords, it's sufficient to use a separate, random hash for each password being checked; it can even reside in the same table/row as the hashed password. For the case of credit cards, this should be the same -- a random salt for each instance of the credit card being hashed. If the credit card number is stored per transaction, a separate salt for each transaction.
There are pros and cons to this approach, but it's sufficiently secure. The pros are the lack of key management; the salt and hash are right there, and don't need to change while still allowing for audit checks of the hash; e.g. does that credit card hash match this known credit card number?
The cons are in search; it's not possible to effectively search for a particular credit card number across many transactions.
Of course, you'll have this issue with external encryption anyway; unless the database is itself encrypted (something only some databases support), you won't be able to search very well. Even then, encrypting at the database or even the table level reduces search effectiveness significantly.
The last few times I worked with creditcard payments, you never really stored the actual CC info on your own servers. You let the Payment gateway handle that. What you ended up with was a transactionID that you could use to verify that the creditcard was still both valid and had the requested amount of cash available. Then once you actually packed the stuff they bought, you'd issue a capture-command to the Payment Gateway.
This approach greatly simplified the process of integrating CC payments on a site, since all you ever needed to know was the transactionID for a particular customer. This ofcourse didn't allow you do to the amazon-"trick" of keeping your CC info for 1-click shopping. If the transactionID got compromised, all it could be used for was collecting payment early, or cancelling the transaction altogether (in which case you'd find out about it when you verified that the authorization was still valid before shipping). The transaction couldn't be used to collect a bigger sum than what the customer had approved already, nor would it allow someone to collect to a different account than what the "shop" was configured for.
Maybe not the exact answer you were looking for, but perhaps it could solve your overall issue without having to spend a fortune on security vendors.
Your assumption that the merchant must store the card somehow is incorrect. Most likely, the merchant is storing a token that it received from the payment processing gateway the first time you used the card. The token uniquely identifies the combination of merchant and card. Subsequently, you can make purchases from that merchant without supplying your card number again. If the merchant's database is compromised, the tokens are of little value to the attacker. They're only valid for that merchant, and they can all be canceled at once when the breach is detected.
In some situations, encryption keys are stored not on disk but on some hardware device. Either a special encryption server is used to do the encrypt/decrypt or the decrypt is done using a key stored on, say, a hardware dongle. This way, a hacker cannot steal the decrypt keys without stealing the physical device containing them (since the key never leaves the device).
Another method I have seen is to store encrypted data in a database/datacenter that has no direct connection to the outside world (you can't hack what you can't access). An interface server sits between the "secure" part of the network and the "Internet-facing"/"insecure" part of the network as a proxy. Forcing secure traffic to funnel through this security choke point can make it more difficult for an intruder to access the secured data.
Neither of these mean your data is perfectly secure, of course.
As an merchant you can choose to store the CC data in your own database or outsource it to third party providers.
Third party providers like IPPayments or major banks like Westpac in Australia are level 1 PCI compliant. For web applications you can choose to use a payment acceptance web page (presented somewhere in your customer's workflow) from them branded for your company. For windows apps (e.g. you company's CRM app) and recurrent payments they generally have a gateway usable using their API that provide a tokenisation service, that is they accept a CC number, registers it and return an unique token that just looks like a CC number. The token can be safely be stored in your DB and used for any further transactions, batch payments, reconciliation etc with the bank. Of course they big issue is operational cost per transaction. For a utility that takes monthly credit card payment from a million customer the transaction cost can be substantial.
If you choose to store the CC number in your own DB triple DES encryption is sufficient. A better option is to you transparent encryption in DB as offered by Oracle advanced security or SQLServer where even the DBA cannot decrypt the CC number. Then there are onerous responsibility for key management, backup, physical security, network security, SSL transmission, changing default settings of all server equipments and firewall, anti virus, auditing, security cameras and on and on ...
First of all if you deal with credit card numbers, you will need to become PCI-DSS compliant, and once you store numbers all 12 sections of the PCI-DSS spec will apply to you. Thats a major cost to most organisations, and if you don't have the time, resources and financial means, you should not go down the path of storing credit card numbers.
We have gained PCI-DSS compliance on a Windows based e-commerce system that stores credit cards. It uses a 256 bit AES encryption. The key itself is encrypted using Windows DPAPI meaning it can only be decrypted by a process running under the same user account as the one that encrypted it. The encrypted key is stored in the registry.
The key is rotated every 12 months, and a backup key copy is stored broken into 3 parts A,B,C and spread over 3 USB drives, each held by a different person. Drive 1 has A+B, Drive 2 has B+C, Drive 3 has A+C. So any 2 drives are required to construct a full key (A+B+C). This scheme is tolerant to the loss of any 1 of the drives. Key parts themselves are encrypted with a password known only to the drive owner.
To answer your specific question, it is possible to store the credit card encryption key encrypted on disk. The key encrypting key can derived from a passphrase that must be entered when the server is started. Shamir's secret splitting scheme can be used so that k out of N shares are required to construct the secret that will be used as key encrypting key. The decrypted encryption key/secret is then stored in memory. If the server has to be restarted, then you need k shares. This is of course a big overhead and most merchants I know do not implement this. They do however usually store the key separately from the encrypted data for some intermediate security, so access to one does not automatically mean access to the other in entirety (still very bad though).
I deleted contents of my original post since that did not directly answer the question. Suffice it to say that key management and correct encryption are an important piece but still a small part of the story.
PCI auditors cannot possibly ensure that everything is done correctly.
If you want to eliminate any credit card stealing headaches, hash them using salt values not stored in the database (in addition to salt values stored in the database). Hashing them with any modern hashing algorithm will pretty much put to rest most issues with credit card theft but it does mean consumers must re-enter their credit card on each purchase. Having worked on a project that dealt with storage of credit card numbers, I found that hashing them cut security review costs by an order of magnitude (granted that project was before PII concerns).
If you are going to use symmetrical encryption, then you enter a new realm of complication that all comes down to management and control over the decryption keys. I will say that even if you hash the credit card numbers you will still need to deal with reversible encryption since all PII(Personally Identifiable Information) must be encrypted. SQL Server 2008 has a new Extensible Key Mangement plugin architecture which lets use third-party vendor programs to manage control over the decryption keys including split keys.
For more info:
Deploying SQL Server 2008 Based on Payment Card Industry Data Security Standards (PCI DSS) Version 1.2.
any automated system for decrypting encrypted information is going to be completly insecure. By automating the process you are defeating the encryption. Any encrypted data should only be decrypted by a user entered secret key.
I'm writing a system where, as usual, the client is asking for a convenience "remember your credit card details" option.
I've told them that this is in all likelihood a no-go. However, I did have a good idea (tm) just now, and seeing that Good Ideas in Encryption(tm) are actually Bad Ideas (tm), I thought I'd put it up for review here and see what holes can be punched through it.
Essentially, I'm thinking of xor'ing the credit card information plus some message signature using a one time pad that's generated per client. This pad is stored as a cookie variable on the client's browser.
Next time that user tries to place a purchase, the pad is sent to the server, and if the server can properly decode its encrypted data, it shows the credit card information as already being filled. (The cc info isn't actually transmitted back). The server will never store the pad in anything more than memory or page file. In fact, I intend to have the pad be sent twice: once upon arrival on the CC page (where the server checks if it should ask for CC information), and once on CC submission to get the actual information.
The user will also be instructed that their information is "partially stored" in their cookie cache, meaning that they will expect that if their cookies are flushed, their CC information is lost.
Let me know where you think this scheme is horribly failing.
Sounds sketchy, and I'm pretty sure you're misusing the term "one time pad."
Instead of going this route, look into using a service like Authorize.net's Customer Information Management. Basically, you give them the card info, and they give you back an ID that you can use to charge the card. The ID is linked to the website's merchant account, and can't be used to charge the card with any other merchant.
It's much, much safer, and should get you the same results.
Note: I'm not endorsing Auth.net or its CIM. It's just the example I'm most familiar with.
Storing the pad client-side leaves it vulnerable to XSS, I would think.
Technologically: flawed.
Legally: probably flawed. talk to a lawyer.
A one time pad only works if the pad is securely kept secret. Storing it in a cookie definitely doesn't count as secure or secret (it's sent to and from the server, it's dropped onto the user's machine, which might be a public terminal or shared machine). This is a really bad idea. It's a clever idea but ultimately very flawed. I suggest you read the PCI compliance documentation and do what other people do which is (generally speaking):
Don't do it.
Use a payment processor that will securely store the CC and handle billing (i.e. PayPal).
Setup a separate and strongly secured payment gateway, this machine only processes credit card transactions, and it in turn accesses a secured machine that stores the credit card data.
Remember that storing credit card numbers will basically violate PCI and will probably violate any merchant agreements and might even be illegal in your jurisdiction (privacy laws, etc.), consult a lawyer please.
Don't do it. Seriously. Find a payment processor who will handle this for you.
If the credit card is being stored client side then you're storing it with the key which means it's vulnerable.
If you are storing the credit card server side then you don't need a key of an encryption key stored on the client.
It sounds like a very dangerous situation if what you are describing is a case where the user is not only not being given the option whether or not they want to store their details but is also going to have them re-populated without having to authenticate in any way. I'd be pretty happy if I came along to an internet cafe and got the credit card details fields pre-populated for me!