I had reported the hash collision bug via Bugcrowd (independently but after OP). Their response was they have upgraded from MD5 to SHA256 when the bug itself has nothing to do with encryption type but rather how you construct your string. They had asked their clients to upgrade to SHA256 version of sdk saying it will provide better security than MD5 but actually in that version they sneakily updated the way they constructed the string (which was the actual problem) and no one knows about this. They should atleast be true to their customers who use their sdk for payments.
This article has been so useful to me over the past 5 years. I've worked at a number of places that have tried building their own signing schemes and this, plus the definition of the later AWS Signatures that resulted, have helped build stronger solutions. Better yet, it's helped the company understand the risk with building anything crypto related yourself.
What's with this weird message flow where everything flows through the client -- is this a "feature" of 3D Secure?
I've implemented plenty of CC billing over the years but always submitting from the backend server to the merchant API directly - never from the client (that includes Stripe-like JS solutions).
Classic blunder for a backend to trust the client to handle the 'amount' field in any way. Feels a lot like the good old "store the cart total in a hidden field and trust it verbatim" bugs all the shopping carts used to have!
If the Primary Account Number (PAN) and CVV go directly to the merchant and bypass your servers, then you can drastically reduce your PCI scope.
Most solutions have a merchant server that allows a cross-origin POST or uses an iframe. In either of these methods you exchange the payment information for a low value token that you then send to your server. Your server can exchange that low value token for a high value token and use that to charge people's cards. This is better for everyone involved because there is less of a chance that the PAN or CVV will be exposed.
I think there's a bit of a confusion in terminology here, but I haven't finished my morning coffee yet so apologies if I misread your comment.
Merchant = yourShop.com
Merchant Bank = Big Commercial Bank for yourShop.com
PSP = paymentGateway.com
Card Network = Visa
Issuing Bank = JoeBlogsBank.com
PAN (Personal Account Number) = 16 (can be different in some card schemes) digit card number, CVV, expiry date
Customer = Joe Blogs
The hosted payment interface is provided by the PSP so that the merchant doesn't need to have a PCI-DSS compliant system at all.
As you say, this means that no PAN data needs to be captured or retained by the merchant systems and instead only an auth code and status message are used as proof of payment, or capture if we're exclusively discussing credit cards.
In the 3DSecure context, there is another level added, with a password handled by the Issuing Bank. From what I saw, the web form for entering this password is not implemented by the PSP but by the issuing bank - the PSP redirects you to the bank's website for entering the password, then you are redirected back to the PSP and merchant. This is mostly implemented by smaller PSPs and stores (probably because of lower fees when using it, as the card holder will have a hard time to dispute a 3DSecure transaction). From what I saw, most of the US-based and large payment gateways bypass 3DSecure.
You are correct. 3DSecure add a new layer of protection provided by the card network (visa, mastercard, etc) IIRC, so not the issuing bank itself. US based e-commerce follows a different set of rules and I would rather not go into that.
I was an architect at a major PSP for 6 years.. I've actually forgot most of it by now :-)
Not 100%. This removes chargebacks due to theft (or I didnt make that transaction) I believe, but people can still chargeback for many reasons - disputing quality of product/service being the biggest headache, product not being delivered (or supposedly) another..
That's what's funny about PCI scope. The JS is controlled by the server, so that the server doesn't presently see the card number, should be irrelevant.
I assume exposure is equal to passing the card to a merchant gateway on the backend as it is for passing the card to a merchant gateway on the frontend. It's nonsensical to assume the threat profile on the two are any different.
Certainly it matters if the backend is storing the card number in any way. Or if the backend is transmitting the card number in any way beyond the established TLS channel.
The card number be encrypted as quickly as possible and shoved off. I always find the best place to do it is on the backend. If you can afford it, you get the PCI audit anyway, because not having it is just an excuse to be sued, right?
Hmac libraries expect the message to be a string. It protects you against length extension attacks (& co). This was a bug in how they converted a map(string -> string) to a single string to sign. Hmac or not, you'd still need that, and if your bug is in there, no hmac will protect you.
> To exploit this we need to construct a string which will be a valid request, and also a valid MIGS server response.
Whoa, crypto 101 fail.
In a secure channel between two parties, you either key the two directions differently or you explicitly mark the directions in the authenticated data. You never really on the next layer down to notice the the message was produced by the wrong party.
From looking at the example messages in the article, it's totally unclear to me that anything binds the response to the request that generated it, either. This could make replay attacks possible. Or maybe even more fun attacks: buy two things, but cancel one partway through and use its MIGS reply for the other one.
For the USA-based folks missing the context, the article describes vulnerabilities in a system called 3D Secure, also known as MasterCard SecureCode, and Verified By Visa.
It was really popular like 10 years ago in the US, too — the banks would let or require you to set credentials for online purchases for your credit card number, usually on first use with an online vendor like Newegg. Of course, it was implemented by a third party on each bank's behalf, so, for better or worse, it was a separate set of credentials than your online banking. And, of course, being implemented by a third party, there was no sign of whether the domain name of such third party was really authorised by your bank to accept your PII — great way to teach folks to provide PII to random vendors you've never ever heard of (but, look, the page has your bank's logo, of course it's legit!), not to mention that it was all implemented in frames (possibly on purpose to conceal the domain name of the shady vendor your bank chose), and with a plentiful of pop-up windows with a hidden URL bar at that, too (of course! So 2000s!).
Basically, a really great and secure standard compared to just the static credit card number you share with each vendor, but, of course, totally ruined by the actual implementations, in the US, at least.
To my knowledge, no single US retailer or bank uses it anymore (IIRC, Newegg and ZipZoomfly did used to possibly require it back in the day). A couple of years ago, I asked Capital One why my online transaction in Russia wasn't coming through — didn't even reach the usual 3D Secure stage, and they claimed that they haven't supported it for ages! (Of course, the infra is still all there, but now it just shows up to the user as a mere splash screen when shopping on foreign websites; still very popular in Russia with all the payment gateways.)
Basically, the tech is really useful for reasonable authentication, but suffered the same fate as the Chip in the States back in 2000s (ironically, Target was one of the first vendors to use it in early 2000s). Now if your purchase is declined or you're a new customer with a big discount warehouse like Provantage, you just have to call them offline and verify your identity manually; how smart!
I'm actually having issues in the last couple of weeks w/ Verified By Visa with Chase requiring manual verifications, which wasn't an issue a few months ago.
I'm not really sure it's going away, through — it's just pretty much on maintenance mode, and still heavily used outside the US.
Edit: My report to them: https://imgur.com/1f2jU05