Hacker News new | past | comments | ask | show | jobs | submit login
The Life of a Stripe Charge (petekeen.net)
67 points by axelbouaziz on Jan 20, 2014 | hide | past | favorite | 35 comments



"Because your server-side process never knows the real card information, it doesn't fall into PCI compliance scope."

WRONG! The payment code is delivered by a response from the server-side & as such it is in scope for at least PCI section six. As an example, if the JavaScript code or reference comes via an HTTP & not HTTPS request it can be tampered with on the wire & the code replaced with code from the attacker, thus getting in the middle of the transaction. If there's an SQLi or persistent type-2 XSS flaw on the server side an attacker could similarly modify the code there. People need to stop believing that tokenization does anything more than remove the need to protect credit-cards in memory on the server side & pay attention to their security. Since the concept of tokenization hit the scene I'm seeing worse security around card transactions than I ever have before in my reviews. Worse, people convinced that tokenization entirely clears them from PCI responsibility tend to be argumentative & resistant to what I believe to be common sense guidance. Luckily the PCI council has been made aware of these issues and provided some clarification about tokenization:

https://www.pcisecuritystandards.org/documents/Tokenization_...


Thank you for the link. That sentence is wrong, I'll fix it to say something along the lines of "your PCI compliance scope is reduced to the things Stripe requires you to do on their security guidelines[1]"

(edit: For what it's worth my book does not make the same mistake, and in fact has a whole chapter dedicated to PCI and HTTPS implementation.)

[1]: https://support.stripe.com/questions/do-i-need-to-be-pci-com...


So do Stripe merchants have to fill out and/or file any PCI DSS compliance materials?


According to Stripe themselves, no. Honestly most of PCI is common-sense stuff that you should be doing anyway (firewalls, restricting access, etc) but the compliance audits are strictly optional with Stripe as long as you're serving over HTTPS and are using their tokenizing javascript.


Wow, I just checked their guidance & they absolutely need to reconsider their guidance:

"Do I need to be PCI compliant? What do I have to do?

Anyone accepting credit card payments must be PCI compliant—but with Stripe, it's easy:

Serve your payment page over SSL, i.e., the page's web address should begin with "https", not "http".

Use Stripe.js as the only means by which you accept payment information and transmit it directly to Stripe's servers.

By taking these steps, you completely avoid handling sensitive card data, and keep your systems out of PCI scope."

So use SSL and Stripe.js and I guess you can use all default passwords, not implement anti-virus and allow XSS, SQLi, command injection, and code injection vectors to run wild on your server? After all, none of those could possibly be used to nuke Stripe.js and replace it with code of choice by an attacker?

They are providing highly suspect guidance for sure.

https://stripe.com/us/help/faq#pci-compliance


Just over 'SSL' itself isn't enough, even if it was enough. There are so many broken configurations and weak ciphers that just having a lock on your url bar isn't enough.

https://www.ssllabs.com/ssltest/index.html


Yup, and that's just the start of the issues when it comes to trying to side-step PCI compliance through claiming tokenization takes care of it all.


Then Stripe might want to reconsider their guidance in light of the PCI guidance on tokenization. Reference:

"2.4.2 Merchant Responsibilities"

https://www.pcisecuritystandards.org/documents/Tokenization_...

The only way out of being responsible for PCI compliance would be to offload the entire transaction to the payment provider. This means sending the customer entirely off domain of the merchant (iFrames don't get you there) so that the entire same origin of the transaction is within the complete control of the payment provider. The second the merchant loads an iFrame or any JavaScript within their same origin, they are accountable, period.


After reading the doc and paying close attention to that section, it's not clear to me what the Stripe problem is. I didn't see anywhere that the Stripe approach would not comply.


Because the merchant is still responsible for delivering the payment form within their same origin in a secure manner which means that the merchant must secure their hosts so that the delivery of that payment form cannot be tampered.


Awesome!


If the PCI guys really want small businesses to be careful around tokenization, one might suggest that publishing yet another very long document about technicalities is rather self-defeating.

It's the new generation of payment services like Stripe that are offering out-of-the-box forms and vaults and tokenization and so on. These services are doing well precisely because they manage to make the card payment industry dinosaur and its anachronistic practices and endless bureaucracy at least moderately competitive again for small/medium businesses.

However, if the underlying card schemes and their PCI attack dog start trying to hard to throw their weight around in this sort of area, the industry is going to haemorrhage business to alternative payment methods even faster than it already is.


The problem is when companies like Stripe provide misleading or patently false guidance in order to build their business. It's very amazing when people buy-into the idea of completely side-stepping PCI by implementing SSL & some Javascript within their same origin.


Where did this same origin fixation you have come from? You keep mentioning it, but stripe.js or checkout.js would normally be loaded directly from a subdomain of stripe.com over HTTPS, and the pages that load that JS, which really are coming from the vendor's own domain, are also required to be served via HTTPS according to Stripe's guidance.

To compromise that set-up without compromising the communications infrastructure or Stripe itself, an attacker would need to be able to modify the files served from the vendor's system. Anyone who can do that can just as easily serve a page that puts a form up asking for card details but then simply e-mails anything submitted to the accountant of their favourite Nigerian prince, never going anywhere near Stripe. So what is it you're concerned about here and how do you think anything in PCI DSS actually makes it better?


The reference to the Stripe JS must come from the same origin of the merchant. Look at Stripe's own example, the form is hosted in the same origin of the merchant, therefore if there are any security flaws which would allow a bad guy to publish their own JS or markup within the merchant domain the security of the collection form is done. It doesn't matter that the JS is loaded from stripe.com because that reference can be stopped or replaced.


So what would you have everyone do instead, in your world where complying with overheads imposed by PCI and the like don't matter?

Sure, you could mandate that every legitimate small business collecting credit card information be subject to heavyweight audit processes and be compelled to institute enterprise-grade everything.

If you could actually get away with that, then most small businesses would either switch to charging via other mechanisms and/or fail. It still wouldn't stop fraudsters who don't care what you or PCI or anyone else says from putting convincing-looking forms on their convincing-looking sites and exploiting anyone who is willing to put their numbers in.

In practice, I doubt you actually would get away with that kind of clamp down today. If the card industry really decided to cause serious harm in a part of the economy that generally drives growth and recovery by enforcing its antiquated rules against small businesses, sooner or later it could wind up facing anything up to primary legislation to put it back in its place as governments acted to protect their national interests. Not only would that make economic sense, it would also probably be a big win for just about any politician to do it, given the current anti-bank sentiment almost everywhere.

Of course this is all absurdly hypothetical, because in reality as long as small businesses are being reasonable and using common sense when it comes to securing their facilities, it is very unlikely the card schemes have anything to gain by hassling them or the modern payment services they use. I imagine they're more worried about national chain stores losing card details by the hundreds of thousands or millions.


If you're going to accuse a leading provider of "misleading or false guidance" you need to provide some evidence.


The PCI council has already provided the evidence for which I've already provided the link. Read the PCI guidance surrounding tokenization. It makes it very clear. Just think about this rationally for a second. If you are a merchant who uses a bit of JavaScript provided by a payment provider and customers enter their credit-card information into the form created by that JavaScript, but instantiated by an HTTP response from the same origin of your domain how do you as a merchant side-step responsibility for PCI compliance? The simple fact of the matter and as outlined in the latest PCI guidance, you don't. Now if you instead send your customer directly to Stripe and they collect the credit card information within their same origin, then yes, PCI side-stepped. Stripe and any other vendor in this space need to behave responsibly and ensure their customers understand their PCI responsibilities.


+1000

You should also mention SDLC process to make sure that a rogue developer of the merchant app doesn't send credit card numbers to a server somewhere else.


Is it really a good idea to be making HTTP requests with the card number and CVC in the URL?

I get that it's over HTTPS, so the whole thing is encrypted, but won't the URL still be saved in my browser history, which will end up on disk and be available to anyone who gets on to my computer?

If the request was a POST method instead, you'd avoid these possible weaknesses. Or am I missing something?


From the article:

> Stripe POSTs at a /tokens API endpoint over https, which means everything is encrypted including the query params


It's still a little unclear: It says that it is a POST, but the URL in the box above contains the card details. Further, the bit of text you quote goes on to say:

> ...including the query params. These params include the card number, expiration date, and CVC

The URL they give as an example is:

https://api.stripe.com/v1/tokens?email=foo%40example.com&pay... &card[exp_month]=4&card[exp_year]=2014&card[name]=foo%40example.com&key=pk_test_6pRNASCoBOKtIshFeQd4XMUh&callback=sjsonp1390180955159&_method=POST

So are these params in the URL, or not?


No, the output in the box is from the web console, which uses the GET-style URL as a concise way of showing POST requests.


Ah, I see. Thanks for the clarification!


We're an ecommerce company who have been dealing with the baggage of "1-click buy" that we implemented a year back. To persist the cards we had to build our own infrastructure thereby increasing our PCI exposure. The yearly audits, honestly, are costing us a fortune. I need to make a business case around getting rid of the card related infrastructure and using some third party that provides tokenization-as-a-service. Are there any vendors out there who do that?

After doing this,will my PCI exposure reduce significantly? As long as my customers are entering their CC details over the vendor's secure page and I'm making encrypted API calls to their service on HTTPS pages (like Stripe) do I still need to get PCI Certified?


I never used Stripe before, but seeing the tokenization method without revealing information to third-party backend to stay compliant just makes me cry. Smart solution.

EDIT: Agree with the top commenter. 3rd party website can always be compromised. Tokenization only takes care one side of the story.


I don't understand why Stripe needs to know my customer's credit card number.

Wouldn't it improve security if my web page encrypted the credit card number using Mastercard's public key before sending it to Stripe?


If services like Stripe accepted already-encrypted credit card numbers, couldn't someone just steal the already-encrypted credit card numbers and run them through Stripe?

Also, resting the security of the payment infrastructure on a single keypair (per network) seems a bit risky. You'd probably want a more sophisticated infrastructure which individually identifies players and allows for revocation, ala chip & pin.


> If services like Stripe accepted already-encrypted credit card numbers, couldn't someone just steal the already-encrypted credit card numbers and run them through Stripe?

OK then encrypt the credit card number + merchant ID

> Also, resting the security of the payment infrastructure on a single keypair (per network) seems a bit risky. You'd probably want a more sophisticated infrastructure which individually identifies players and allows for revocation, ala chip & pin.

Then perhaps Mastercard could have a separate public/private key pair for each merchant. Although even a single key pair for each card network would still be better than the status quo, wouldn't it?


>OK then encrypt the credit card number + merchant ID

That would be significantly better.

>Although even a single key pair for each card network would still be better than the status quo, wouldn't it?

If it gives people the impression that they no longer need to even try to protect their infrastructure because the card numbers are already encrypted, then yes.


In reality, it doesn't matter what controls you implement in the JS including DOM resident encryption. If your network, your server, or your application is vulnerable a bad guy can simply change the payment script directly or even entirely overwrite the DOM with their code. When it comes to PCI compliance companies are responsible for securing the end to end payment path which includes the security surrounding the delivery of the payment form.


Sure, encrypting in Javascript would not affect the security of my server and network. But it would increase security of the system as whole, wouldn't it? That is, an attack on Stripe's servers would be less likely to reveal credit card information.


The most probable place of attack is at the merchant where a bad guy would simply remove the Stripe JS code or modify the DOM in a way to replace the credit-card collection form within the merchant same origin. Please reference the PCI DSS. It states that the controls outlined in that document apply to all processing components. A merchant website calling the Stripe JS within the same origin of their domain eg., http://my.ecommercesite.com/payment is a payment component, period. The only way to remove PCI responsibility would be to load the payment page at stripe.com so that the browser URL shows https://stripe.com/...

https://www.pcisecuritystandards.org/documents/PCI_DSS_v3.pd...


I agree with everything you say. I agree that the most likely point of attack is the merchant's website. I agree encrypting the credit card number in javascript would not remove PCI responsibility from the merchant.

But I don't see how that affects the question of whether the merchant should encrypt the credit card number before sending it to Stripe. Are you saying that such a practice would not improve the overall security of the system? Or that there is no need to improve security if the system is already PCI compliant?


Right, encrypting it beforehand makes no difference whatsoever & the merchant must consider that they have PCI obligations so long as they host the form within the context of their same origin.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: