Stripe Card info best practices etc - stripe-payments

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).

Related

How to develop a crypto exchange leveraging on third party API like coinbase, blockchain.com

I got a request as a developer to develop a bitcoin exchange site like https://mypatricia.co/ or https://instantcoins.ng/ I am to leverage on third party API like Coinbase, blockchain, it could be anything reliable API.
Users will be able to buy and sell bitcoin. For instance USER A makes an offer. USER B is interested in USER A's offer. When USER B clicks a button, with be a switch from USER A's wallet to USER B's wallet. Before the EXCHANGE is done. USER B is prompted to make payment in local currency.
I have been looking at https://developers.coinbase.com/api/v2#introduction https://api.blockchain.com/v3 I dont know how to go about it.
Is there any other better ones to work with?
There will be some other endpoints like
Where users get list of their orders
check wallet etc
I will appreciate your contribution
This is a very broad topic, so I'm just going to tackle few key points.
Dependency on third-party blockchain data
You can get rate limited
You might be a subjet to a man-in-the-middle attack
The source might (intentionally or unintentionally) send incorrect data.
The data is usually delayed
You'll most likely need to use another tool to create deposit addresses (since the third-party tools will allow you to create only limited amount of addresses on your account).
It's very risky and unreliable to use a third-party data. It's an industry standard to run a full node for each cryptocurrency you work with and access the blockchain data from your own node instead of a third-party API.
Escrowing the offered amount
As per your example, you need to make sure that user A is actually going to transfer the BTC. Since there are no smart contracts in BTC, you need to act as an escrow.
So you need to accept the BTC from user A to their deposit address (only your site should have the private key to this address) before you even allow them to pass their order into the queue.
Order list
Since you're going to be storing the order list on your side, you need to create a separate database and CRUD endpoints to maintain the order list.

Stripe token - why isn't data-amount included in the token

I've been playing with stripe recently and while i fully understand that the token hides the clients credit card details from the server. This tutorial suggests that the server should not rely on the data-amount since it can be changed by the client
Don’t Rely on the Form’s Price
A frequent mistake stems from using form data to contain the price of
the product being purchased, possibly via a hidden input. Because a
user can easily edit this input’s value, it’s unwise to depend on it.
Always fetch the price of the product from the server-side. Never rely
on the form to tell you. A simple database query is the preferred option.
Can someone explain to be why stripe does not include the data-amount value as a parameter in the token generation? Is there not a potential for a server side code to change the agreed price and overcharge the client.
The token is a placeholder of a pending charge, it does not know how much you are going to charge yet. Once you are ready to charge the card an api request will be sent to Stripe along with the token. The concern about the amount deals with relying on POST data from a form that can be manipulated by the customer.
Its up to you to set the charge amount. For example a hotel could authorize $100 to spend the night but then at check out discover that you used the minibar and then charge $150. Or the auto calculated shipping is off so when you actually purchase the shipping its $5 less and you decide to charge $5 less than your auth.
What you should be doing is calculating the amount to charge the customer, save it via a shopping cart like function in your DB (or serverside somehow) sending the checkout form to the customer then using the previously calculated amount run the auth then the charge.
Form data can easily be changed by the end user. Just open the page and right click (in chrome) and click inspect element. You can then arbitrarily change form data. So if you were using that, the user could set the price to $.01 for your $1,000.00 product.
The propose of tokenization in the PCI world is to keep sensitive data off your servers. Otherwise you would collect the PCI data yourself then send the amount off to the processor along with the PCI data. By not ever having the sensitive data touch your systems you save a ton of money and headache in PCI compliance. See this 115 page document: https://www.pcisecuritystandards.org/documents/PCI_DSS_v3-1.pdf
Hope that helps, Please comment and I'll try to help further if it doesn't.

Separating BIN from Stripe.js

I want to use Stripe for payments, but want to be able separate the BIN/IIN from the 16 digit credit card number the user enters, before Stripe.js encrypts all the digits bar the last 4 ie. ******1457
Basically, I want to integrate MaxMind into the my Stripe powered payment page, and have MaxMind do a few checks on BIN matching before the transaction is captured by Stripe.
Stripe says this isn't supported currently, yet they do suggest using MaxMind for identifying PrePaid cards (which is done via BIN identification).
Any ideas what the correct answer is (hello Stripe:) and how to accomplish what I need?
Since you're using Stripe.js, don't overthink it. ;) This is just a matter of calling your own code before (or possibly instead of) calling Stripe's. Until you call Stripe.card.createToken, your form data is untouched.
Do note that, like Stripe does, you'll want to do the number manipulation client-side to avoid your server falling into PCI scope. An isolated BIN/IIN is not (currently) considered privileged data; you can pull it out with substring and then send that willy-nilly anywhere you like.
At that point it's a matter of deciding how durable you want your Maxmind integration to be. If you're not overly concerned with a nefarious visitor overriding your JavaScript, you could simply do the Maxmind check inline, before calling Stripe, via their HTTP API.
This is no longer possible with Stripe.js v3 (the previous answer was from 2013, and v3 was released some time later). This is because v3 is an iframe that is embedded on your page, and it is not possible for you to access the values in that iframe from your page.
In Stripe.js v2 this used to be possible, but actually even handling card details on the client side requires you to have an SAQ A-EP, rather than the slightly simpler SAQ A. Read more about it here: https://stripe.com/docs/security/guide#validating-pci-compliance
For the purposes of identifying prepaid cards, the Stripe API will tell you the card type in the API. If you really need the BIN, you can ask Stripe Support about enabling that for you in the response in the API.

PCI/DSS: Data at Rest

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.

Security review: client credit card# stored on server but with one time pad encryption stored in client cookie

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!

Resources