QRモバイルオーダーに潜む「不正注文」の恐怖と、店舗の利益を死守する多層防御策
固定QRがSNSに流出し、営業時間外に架空注文が続いた事例では、廃棄ロスが通常日の1.8倍に達した店舗もあります。MasterOrderの答えは「もっと強いパスワード」ではなく、開席のたびに席専用セッションを都度発行し、会計で必ず失効させることです。設計優先度は 1. セキュリティ → 2. 動作の安定 → 3. 使いやすさ です。
実際に起きる不正注文パターン
- 固定URL流出型:卓上の共通QRが拡散し、店外・閉店後も注文可能
- ブルートフォース型:PINや接続APIへの総当たり
- 退店後のすり抜け型:会計後もセッションが生き、追加注文が入る
15件の高額トッピング注文で食材コストだけ8,000〜12,000円損失になる例もあります。
固定QR vs MasterOrder(都度発行セッション)
| 項目 | 固定QR | MasterOrder |
|---|---|---|
| 発行タイミング | 店舗共通URLを常時有効 | スタッフが開席した瞬間に席専用セッションを新規発行 |
| 識別子 | 推測されやすい固定パス | セッションID(英字10文字)+入店PIN(7桁) |
| 接続URL(例) | — | /connect?id=AbCdEfGhIj&pass=2376843 |
| PINを載せない方式 | — | Joinトークン /#join=…(Redisで解決、会計で即revoke) |
| 退店後 | URLが生き続ける | 会計で isActive=false。同じQR/PINは404 |
| いたずら対策 | 弱い | 1回の注文はメニュー合計19個まで等の上限 |
システム側のガード(接続・API)
| 対策 | 内容 |
|---|---|
| PIN試行上限 | 失敗超過でセッションロック(423) |
| IPレート制限 | 接続APIへのbrute force抑制 |
| PIN必須Filter | 注文・接続で X-Session-PIN 未設定は401。Controller前でFail Fast |
| スタッフAPI | Firebase JWT+店舗スコープ認可(他店データ拒否) |
| 配信層 | 来客UIはCloudflare Pages(CDN)。WAFでボット制御 |
「QRの中身は、その席の合言葉だけ。前のお客様のQRを使い回すことはできません。」
店舗が今すぐできる3つの運用防御
1. 開席→QR表示を徹底(固定シール依存をやめる)
都度発行の前提は、スタッフが開席してからQRを見せる運用です。
2. JoinトークンQRの活用
PINをURLに載せたくない席では #join= 方式を選択。ログや写真にPINが残りにくい。
3. 会計=セッション終了の徹底
会計未了のまま次の客を着席させない(未会計セッションがあるテーブルは新規開席不可)。
解決シミュレーション
固定QR運用から都度発行へ切替後、営業外の不正注文が週3件→0件、厨房の誤調理クレームが週3件→0件になった店舗例があります。
まとめ
技術詳細は Fail Fast・多層防御の技術解説 を参照。導線体験は 体験用QR で確認できます。