A diner in Kunming, China sat down for hotpot in November 2023 and did something millions of people do every day: she posted a photo of her food to WeChat Moments. Two things she didn’t notice were in the frame. First, the table’s ordering QR code. Second, her phone wasn’t on the most restrictive privacy setting.
Within hours, contacts had downloaded the photo, scanned the QR, and used the menu to submit orders against her table. By the time the staff caught on, the bill stood at roughly ¥430,000 , about $60,000 USD:
- 9,990 portions of shrimp paste
- 2,580 portions of squid
- 1,850 portions of fresh duck blood
The restaurant , to their credit , moved her party to a different table, voided the order, and did not charge her. They then quietly added a “distance limit” to their ordering software so the same trick wouldn’t work again.
This story is now lightly famous in QR-menu industry circles. It’s a useful one because it makes a structural problem concrete: a printed QR code on a table is, by design, a permanent ordering credential. Anyone with the photo can order from anywhere, at any time. If your software trusts the QR alone, you trust everyone who’s ever seen the table.
What every QR-menu vendor gets wrong (and right)
We surveyed the major players for our comparisons before building MobiTaste. There are five common defences in the industry:
- Staff approval before kitchen , Adisyo, Menulux, QRKafe, Restomenum and others default to this. Orders enter an approval queue; a waiter taps Confirm before the kitchen sees the ticket. This is what we picked too , it’s the cheapest, most universal mitigation.
- Pay-on-order with card capture , Square for Restaurants, Lightspeed, most US SMB tools. If you have to put a card down to submit, prank orders are self-defeating.
- SMS-OTP + pre-authorised tab , me&u and GoTab. Phone verification + a $0.01 pre-auth at first order, auto-captured at 3-hour idle.
- Pay-only platforms , Sunday, Qlub, Rooam Pay. They sidestep the problem by not letting guests place orders at all; you only pay a check that staff opened in the POS.
- Physical-presence binding , NFC tags, geofencing, dynamic QR. Real adoption is limited because the trade-offs are steep.
The Kunming restaurant added option 5 (geofencing) reactively. We built options 1, 4-style fail-safes, and per-session caps from the start.
How MobiTaste’s defaults remove this attack
For a fresh signup, the defaults are:
- Waiter approves the first order in every session. The first order
enters
PENDING_APPROVAL. Your waiter sees a card on their tablet with the table, items, and total. One tap to approve and it hits the kitchen, one tap to reject (with a reason) and it bounces. After the first approval, subsequent orders at the same session flow straight through. - Hard limits per session. Even if a Kunming-style attempt slipped
past approval, the request would 429 long before it got close:
- max 50 items per single order
- max 200 items per session
- max 6 orders per session per hour
- max session value (defaults to 5,000 in the venue’s currency) 9,990 portions of shrimp paste 429 on row one.
- Session-bound + idle-expiring table sessions. Each table has a
TableSessionobject. New scans after the 90-minute idle window open a brand-new session with zero approved orders , so even if the same QR is re-scanned from another country, you’re back at step zero (waiter approval required). - Audit log on every order action. Place, approve, reject, status change , all recorded with who did it. If you ever need to reconstruct what happened, you can.
Concretely: take the Kunming attack as a script. From a different country, re-scan the printed QR, place a 9,990-portion shrimp paste order.
POST /api/v1/guest/menu/{slug}/t/{token}/orders
→ HTTP 429 Too Many Requests
{ "error": "max_items_per_order", "limit": 50, ... }
If they trim it down to a small first order to slip past the cap, the
order enters PENDING_APPROVAL and waits for your waiter. Your waiter,
who is at the actual table and can see who is and isn’t sitting there,
taps Reject. The order is cancelled with a written reason that lands in
your audit log.
What we don’t do (yet)
We’re honest about limits. MobiTaste doesn’t currently:
- Verify phone numbers on first order (me&u’s approach , strongest fraud defence but a UX tax).
- Take a card on file before letting orders through (the US-style pre-auth , feasible only where guests carry credit cards).
- Enforce geofencing (TapTasty does this , false negatives in malls and big hotels are a real problem we don’t want to ship around).
When the next Kunming-style incident becomes the standard threat for our customers, we’ll have those layers ready. For 2026, server-side approval + hard caps + session boundaries are the sweet spot for the $10/mo segment , strong defence without the UX tax.
Try it
If you’d like to see the security defaults from the owner side, you can start your 14-day trial and look at the Settings page. The defaults are what every account starts with; you can dial them up or down for your venue.