Hacker News new | past | comments | ask | show | jobs | submit login
Domino's: Pizza and Payments (ifc0nfig.com)
237 points by TheGuyWhoCodes on April 10, 2016 | hide | past | favorite | 56 comments



client-side payments is totally normal, when done right, unlike dominos's's buggy version -- what usually happens is that the vendor sends you to a payment processor, and you pay them, and the payment processor sends a verification token to the vendor, and the vendor delivers your product to you.

Domino's skipped one critical step.


> ... and the payment processor sends a verification token to the vendor

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.


Why not have the payment processor notify the vendor's server directly? I believe PayPal does this.


That's how it works most of the time, at least in my experience.

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.


this is essentially how stripe's implementation works.

CLient side library handles the CC and token generation. Server side you use that token to call stripes backend to process the payment.


Implementing IPN on Paypal is a pain. It is really only required because the normal flow for Paypal is to take the user off your site to theirs and only redirect back to you when the user clicks a link or waits quite a long time. This results in loads of users not making it back, or clicking out of the flow. More modern client-based payments processing tends to happen in-page via javascript or an app.

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.


That's not enough, the vendor needs to verify all the details that paypal sends back are correct.

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.


Because then it's a 3-way conversation with nobody in the center. It's better to have the client do the transaction with the payment gateway, pass the token which they already have to your server on the orderPlace call which you then verify with the gateway. Otherwise the client could be asking for order confirmation before you know about the transaction.


I'm waiting for Pizza Hut to show up next. I refuse to let them save my CC number because their password policy basically ensures that you can't choose a reasonable password.

And if the obvious, public part of the site is like that, I can only wonder what hackers would find probing deeper.


I often wonder what hackers would do if they made it past the front door.

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.


Which pizzahut country are you referring to out of interest? Is this US?


The USA, specifically pizzahut.com prevents you from using any special characters in your password.

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.


One of the things I love about stripe is it allows you to give them the raw credit card details directly (never hits my servers/logs), and they give me back a token. So I can still keep things server side, but I don't have raw credit card information in my server logs/database.


That's exactly what Domino's provider (and anyone else worth using) allows, they just didn't bother verifying the yoken.


It's not that processing payment client-side is wrong, it's that the Dominos app implement it wrongly, or DataCash simply doesn't provide any security feature for protecting against http request data tampering, which I believe the latter is not the case.

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


> Most payment gateway have a security mechanism to ensure the response from payment server have its integrity remain intact.

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.


From what I've seen, most developers understand "the client's sent data cannot be trusted", but they fail to understand how much it entails. It's not merely the forms they send, it's all of it, cookies, user agents, internal tokens that pass through Javascript, whatever. If the client touched it, it's compromised!


My interest is certainly peaked about the 10% off coupons.


The word you are looking for is piqued.



Except that this is not a grammar error ... (s)he chose the wrong homophone.


In an experiment involving 80 Americans

So, worthless.


Here in the UK there is always a 50% off or better deal for mediums and larges. If you can't find one on the page or from a quick Google ringing the store will get it (only ever had to do this at a friend's in Liverpool)


Might be because pizzas are incredibly overpriced in the UK. Most places they are cheap student food, for $5 you can get a meal. Not in the UK.


In Australia users have created userscripts that will track and share voucher codes and their expiry.

https://openuserjs.org/scripts/jehan/Dominos_Pizza_Voucher_C...


Always 25% off with PapaJohns! Use coupon code 25OFF — it's even valid until December 31, 2017.

Unless you mean how they're generated.


Just like pizza tastes better when you made it yourself, it is sweeter when you were able to code your own working coupon generator.


If pizza tastes better when you make it yourself you don't live in a place that has good pizza.


Nothing prevents you from using good ingredients and practicing till you can generate a really good pizza. The one tool you would have trouble replicating, a really high-temp oven, only counts as important for a limited set of pizzas. And you can take steps to get a high-temp oven, if you want to go all-out.


I've done that and on a good day I can maybe replicate the quality of a good place. Surpassing is not happening.


Then you aren't a very good cook.


I don't think dexterdog is referring to places like Pizza Hut or Papa Johns.

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.


Pizza Hut and Papa Johns are to pizza what a Big Mac is to a hamburger.

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.


Or, back to my original point, your local places are not good.


I work for Deliveroo, so answering your question is literally my job.

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.


I've read that the real discounts are in calling the location directly and asking about "walk-in specials." The franchisee doesn't have to yield as much revenue to the mothership when you avoid centralized ordering and thus can extend more price flexibility.


For these discount pizza chains, there is usually plenty of coupons floating around - they even accept 'competitor' coupons. You can probably find some if you search for them on the internet.

But as old adage goes, you get what you pay for.


> But as old adage goes, you get what you pay for.

Fancy cheese on toast?


Expensive fancy cheese on toast.

Not that I don't love pizza. But even with 50% off, those prices...


I'm not sure the adage applies here. When using a coupon you get up to 100% more than you paid for, assuming you're using the not at all rare buy one get one free ones.


Did the author get a bug bounty? If not, is it that companies who understand tech the least also don't understand the value of such things?


From the tone of it, it seems he is graceful that he didn't get into any legal trouble. So I'd bet no, he didn't get any bounty.


£26 for Domino's. Sounds like he got bent over pretty hard. I can't imagine spending ~$37 on fantastic pizza, much less Domino's.


Don't rely on client side data. Pin certificates in mobile apps.


You're still trusting client side data. What's stopping a more advanced user from replacing your pinned cert with theirs.

Don't do any payment processing client side. Your app should be a pretty interface to the actual service running on your servers.


How was he able to see the raw responses from the payment gateway? Do they use HTTP instead of HTTPS to make these requests?


Because the messages were clear at some point on a machine he controlled.

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

[2]: https://mitmproxy.org/

[3]: https://www.charlesproxy.com/

[4]: https://en.wikipedia.org/wiki/Hash-based_message_authenticat...



Why doesn't Google do more to prevent Android apps from being decompiled, inspected and recompiled into modified apps? Yes, there's source code obfuscation, but that only slows down the amateurs.


Because it's not an arms race that can be won? And in most cases, it's a complete waste of time to try?


That depends on how well the obfuscator works and scrambles your code. Does it rename ALL classes, variables, methods and constants to gobbledygook? Does it add redundant code every now and then to add more confusion? If you do all that, then it becomes very difficult to crack even for advanced hackers. But ultimately it should be possible as obfuscation is based on a human logic (though executed by machines) - but it will certainly increase the needed difficulty and dedication to a considerable degree.


Packets, man. It's about the packets. And a failure to pin your certificate.


What about this?

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


That doesn't prevent the main 'exploit', which was just inspecting the traffic of the app externally.


It's still not a problem if the client and server write secure code. because you can still man in the middle the packets, or own the emulator where you have direct access to the applications memory to manipulate it. A server cannot trust a client.


Because that's not security. The security of your system should be able to withstand an attacker that is able to read the source and arbitrarily modify the client. Otherwise you don't really have security -- you're just hoping no one goes through the effort.




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

Search: