Domino's: Pizza and Payments
ifc0nfig.com
ifc0nfig.com
Domino's skipped one critical step.
I would just add one more critical step: the vendor actually verifies the verification token rather than just checking that it exists (since the token is often passed through the client, it can't be inherently trusted either). This should involve either hitting the processor's server or verifying a cryptographic signature, and verifying that the payment associated with the token matches what the vendor expects.
The Stripe/Braintree-style flow is nicest in many ways - they post the card details off to the payment processor, who generate a unique retailer-specific token for the card and send that back to the page. The retailer then uses that to process the payment server-side just like they would have done if they had collected the card number, only without the PCI-compliance issues.
Card details are sent to the processor, a token comes back. You then send the token along with any data relevant to the transaction (which items were purchased, tax zones, coupon codes etc), you then verify on the server that inventory exists etc, and then you send the token (which is only a short-lived represention of the credit card number) and then verify the payment went through, and then you go through the bussines process for delivering your product(s).
Then, and only then do you give back a response saying the order has processed, so the UI can alert the user.
CLient side library handles the CC and token generation. Server side you use that token to call stripes backend to process the payment.
Otherwise you can change the price and paypal will process your new price, then paypal returns a "yup, they paid" message back to the vendor.
If the vendor only checks they paid and doesn't verify all the other details against the basket you can adjust the price down.
I know this because I actually did this at one of my previous companies, we used to sell SMS bundles for use in our POS (point of sale) product. To demonstrate this vulnerability I lowered the price to a penny and bought our biggest bundle.
Because our test system had the payment side mocked* I had to use the live site.
What I hadn't counted on was the fact that our CEO was CC'd in whenever someone bought a bundle. Thankfully the company wasn't too large, so my boss was able to ask me about it and directly feed back what had happened.
* Technically "just not hooked up" rather than mocked.
And if the obvious, public part of the site is like that, I can only wonder what hackers would find probing deeper.
You can see the message here: http://imgur.com/T8R6Fnr
I thought they used to also have limits on the maximum length, but thankfully that doesn't seem to be there when I tested it just now.
Google had to learn this the hard way -- now all links between their data centers are encrypted, previously they thought they were fine. The NSA and the Chinese famously took advantage of this.
Most payment gateway have a security mechanism to ensure the response from payment server have its integrity remain intact. Most of the time by hashing some combination of responses value and shared secret key between merchant and the payment server, and comparing if both marchant calculated value and payment server hash matches. If it doesn't match, then it is safe to to throw an error and prompt appropriate message to said attacker. When implemented as such, the system are expected to immune to such attack as described by the author.
The article is a perfect case study to showcase the consequences when the developer decided to skip the security part. (yes it's entirely up to the web master if they want this or not, the payment server won't care).
I've definitely seen SSL pinning used to this effect. The simple solution to Dominos' problems seems like a server-verifiable transaction token that coming from DataCash (or whatever gateway service). I agree that client-side payment processing isn't wrong -- in fact, it makes more sense than attempting PCI compliance on their middleman server.
So, worthless.
https://openuserjs.org/scripts/jehan/Dominos_Pizza_Voucher_C...
But as old adage goes, you get what you pay for.
Fancy cheese on toast?
Not that I don't love pizza. But even with 50% off, those prices...
Unless you mean how they're generated.
A person who occasionally (let's say once every other month?) cooks themselves a pizza is not going to do a better job at it than a pizza chef (closer to gourmet than fast food) who is making pizzas for 8 hours a day - every day.
And it's not just the ingredients and dough. Very few people have an oven capable of cooking a pizza the way it needs to be cooked.
I never made pizza myself, but my girlfriend makes an amazing one. Other information, _The Fold_ is awesome. The two information are unrelated. There is no way I’m getting out of any attempt at conciliating those two facts where I win.
Don't do any payment processing client side. Your app should be a pretty interface to the actual service running on your servers.
This is what the article means by the payment processing being done on the client: Some client-side code (JavaScript? A mobile app?) would receive the message from the payment gateway, and send the success code to Dominos.
He may have used a debugger[1] to breakpoint the application where the application has a cleartext version of the traffic, however he might have also taken advantage of the fact that even if using HTTPS, if the programmer uses a certificate store the user has access to (which they usually do), they can install a custom root certificate and then use something like mitmproxy[1] or charles[2] to decode the traffic.
What's needed to make this secure is to have a token provided by the payment processing API that the server can verify but that the client cannot produce (or tamper with)[4].
[1]: https://securitycafe.ro/2015/01/28/intercepting-functions-fr...
[3]: https://www.charlesproxy.com/
[4]: https://en.wikipedia.org/wiki/Hash-based_message_authenticat...
> Why doesn't Microsoft do more to prevent C# apps from being decompiled, inspected and recompiled into modified apps?
There's not much you can do when you have a very simple interpreted language (or JITed). Take C for example. Sure, you can take the outputted assembly and turn it into something readable, but because it's been optimized, it's not easy to figure out what it means. C# and Java OTOH compile down to a very simple set of assembly instructions. AFAIK, "stack variables" aren't reused as each variable is referenced by its index. If you were to take the JITed output from CIL or Java bytecode, making something readable would be hard.