はじめに:設計は書いた。怖いのは本番だ
飲食店向けモバイルオーダー MasterOrder を個人開発しています。セッション管理 も 来客注文の冪等性 も記事にしてきました。でも紙の上の設計と、実際に悪意ある入力を食らったときの挙動は別物です。
中野の店舗に入れる前に、ローカルの本番相当環境(Docker + Cloudflare Tunnel)で、自分の手でセキュリティを叩きました。権限の抜け、個人情報の漏れ、注文の改ざん——ここが一番怖かった。
再現手順やスクリプトは載せません。「何を疑って、何が安心だったか」だけ書きます。
来客注文:PIN だけじゃ通らない
まず当たったのは来客 POST です。冪等性の記事 で書いた多層防御が、実際に効いているか。
PIN だけ揃えても注文は通りませんでした。端末 ID と冪等キーが揃っていないリクエストは弾かれます。クライアントが price をいじって送っても、サーバー側の計算が正で、改ざんは通りませんでした。
別卓の PIN を別セッションに使う、といったクロスセッションの注文も拒否されました。ランチピークで「隣の卓の PIN を誤送信」みたいな事故と、意図的なすり替えの両方を想定した結果です。
同一の冪等キーで再送したとき、新規注文ではなく同じ orderId が返る——これも設計どおりでした。厨房に2枚届く恐怖を、もう一度自分の目で確認した感覚です。
Gate と個人情報:店舗メンバー情報の境界
スタッフまわりは D1 Gate Worker 経由です。自動テスト 13 件を流し、権限の弱いユーザーが他人のメンバー一覧を見られないこと、招待中の氏名がマスクされること、レスポンスに内部 UID が露出しないことを確認しました。
飲食 SaaS で店舗の人事情報が他店舗に漏れるのは、技術的にも法的にも許容できません。ここは自動テストを先に厚くした領域で、今回もすべて通りました。
スタッフ API:未認証と他店舗アクセス
スタッフ向け API は、ログインなしでは使えませんでした。他店舗のデータに ID を差し替えて触ろうとしても、403 で止まります。
内部向けの管理系 API も、想定外の経路からは応答しない構成になっていることを確認しました。詳細は公開しませんが、「外部から見えない管理面」がそのまま外に開いていない、という安心は得られました。
レート制限と監査:現場で効くか
PIN の連続失敗や注文の短時間連打には、設計どおり 429 が返ることを確認しました。キッチン向け SSE にも接続上限があり、異常な張り付きは弾かれます。
拒否イベントは監査ログに残り、来客向けの理由コード(WP-MO-002 / 003 など)に対応づけられています。Vector 経由で Cloud Logging にも流れるので、「なぜ弾いたか」を後から追える——店舗トラブル時に効く設計です。
個人開発者としての感想
セキュリティは一度テストして合格、で終わりではありません。今回の環境はローカル本番相当であり、VPS 上の本番トラフィックとは条件が違います。それでも、中野に足で届ける前に自分で叩いておけたのは大きいです。
設計思想を記事にして、実装を記事にして、最後に「本当にそう動くか」を確かめる。この3段が揃って初めて、店舗に顔を出せる気がします。
次は現場導入のオペレーションか、厨房まわりの続きを書く予定です。