fix(security): close coin minting and open write policies
Found while building the org/redeem layer; all exploitable with the public
anon key that ships in realtime.js, or with a player's own session.
- complete_match, award_coins and the match/queue functions were executable
by anon and players: one REST call paid win coins to anyone. Service role
only now; every caller is PHP with the service key.
- battlepass.php credited whatever "coins" the request carried, to anyone,
as often as asked. The server now decides the reward, needs an active
season and an unlocked tier, and pays each tier once.
- The legacy api/ludo.php let any player end any ludo match with any winners
and get paid. It, api/domino.php and api/multiplayer.php were unused by the
app and are removed.
- Shop, challenges and daily reward wrote balances with the player's token,
which only worked because players could PATCH their own coins over REST.
They write with the service key now; the shop deducts only if the balance
is unchanged (a double tap cannot pay twice), refunds if the grant fails,
and records its transaction (the old insert used a missing column).
- Policies: anyone could delete any ludo/domino/backgammon match, rewrite
queues, groups and the theme, insert an "accepted" friendship with anyone
and post into any chat. Writes are service-role only; every read and
Realtime feed is unchanged. Group members read only their own memberships.
- profiles-guard.sql (applied after this deploy): a player's token may change
only cosmetic profile fields.
Also the org-unify / redeem SQL layer and its contract (docs/redeem-contract.md).
Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
Showing
api/domino.php
deleted
100644 → 0
api/ludo.php
deleted
100644 → 0
api/multiplayer.php
deleted
100644 → 0
docs/redeem-contract.md
0 → 100644
This diff is collapsed.
This diff is collapsed.
Please register or sign in to comment