← 回主控台
🔐 ArenaMate 權限稽核 — RLS 上鎖清單
稽核日期 2026-07-16。起因:「每個功能真的都有做權限過濾嗎?」
一句話:除了金流表(上次已鎖),全站 79 張表的「寫入」權限本來都是敞開的——任何登入者(部分含未登入)繞過 App 直接打資料庫,就能改任何人的資料。已完成:6 批乾淨表(約 55 張)全部上鎖並實測(模擬登入驗證「別人改被擋、本人/幹部放行」)。剩約 10 張「比賽結算表」(評分/戰績/信任分/比分)因為結算在手機端跑、會改所有參賽者的列,要先把結算搬進 server RPC 才能鎖 → 見文末。
圖例:public = 連未登入都能寫(最急)
authed = 任何登入者能寫
已鎖 = 本次/上次已修
✅ 已鎖好(不用再處理)
| 項目 | 原本的洞 | 已改成 | 狀態 |
| 10 張金流表 | 寫入全開(曾全 using(true)) | 綁擁有者/幹部;費率不吃 client 值 | 已鎖(上次) |
| arena_team_join | 零檢查 + 開放 anon → 任何人把任何人加進任何隊 | 幹部或本人 + 擋 anon | 已鎖 |
| coach_release_slot | 可繞銷課閘門提前套現 | 只留 server(死碼 caller 移除) | 已鎖 |
| arena_notify_direct | 冒名對任何人發任何通知(釣魚/洗版) | 限該館幹部 + kind 白名單 + 擋 anon | 已鎖 |
| arena_complete_bracket_session | 可關掉別人賽事的場次 | 限該賽事幹部 + 擋 anon | 已鎖 |
| arena_bump_player_sport_season | 可把任何人 SLP/XP/排名灌爆 | 登入 + server 上限夾住 + 擋 anon | 已鎖 |
| 65 支測試/demo/teleport RPC | 全 anon 可打、會改正式資料 | revoke anon(你登入還能用) | 已鎖 |
✅ 6 批乾淨表 — 已全部上鎖並實測
以下 6 批(約 55 張)都已寫上「誰能寫」的條件、線上實測通過(模擬登入:別人改被擋、本人/幹部放行)。下表是每張的規則,供對照。各批內 public 的也一併鎖了。
批 1 · 帳號 / 身分最高優先:可改任何人身分
| 表 | 是什麼 | 現況 | 提議誰能寫 |
| user_profiles | 名字/性別/生日/頭像/LINE | authed | 只能改自己 |
| gym_athletes | 每館的球員身分 | authed | 本人名下 或 該館幹部 |
| athlete_follows | 追蹤 / 好友關係 | public | follower=自己(保留掃碼加好友雙向寫) |
| athlete_trust · athlete_pass_progress · athlete_season_stats · gym_athlete_sport_stats | 信任額度 / 通行證 / 戰績統計 | authed | 只走 server RPC |
| gym_password_history | 場館密碼箱歷史 | authed | 該館幹部 |
批 2 · 場館治理可改/刪任何場館
| 表 | 是什麼 | 現況 | 提議 |
| gyms | 場館本體 | authed | 該館 owner/admin |
| gym_settings · gym_venues · gym_sports · gym_day_hours · gym_schedules · gym_special_dates · gym_special_sessions · gym_fixed_sessions | 場館設定 / 場地 / 時段 | authed | 該館幹部 |
| gym_coaches | 場館教練名冊 | public | 該館幹部 |
| gym_access_checklists · gym_access_logs | 進場檢查 / 紀錄 | authed | 該館幹部 / 相關人 |
批 3 · 戰隊可改/刪任何戰隊、加踢任何人
| 表 | 是什麼 | 現況 | 提議 |
| gym_teams | 戰隊本體 | authed | 該隊幹部 |
| gym_team_members | 隊員名冊(加人已走 RPC,直接寫還開) | authed | 該隊幹部(本人可退隊) |
| gym_team_invites | 戰隊邀請 | public | 該隊幹部 |
| gym_rep_teams | 代表隊 | public | 該館幹部 |
| team_honors · arena_team_challenges | 榮譽 / 約戰 | authed | 系統 / 隊幹部 |
批 4 · 賽事可改別人賽事/比分/裁判
| 表 | 現況 | 提議 |
| gym_tournaments · gym_tournament_entries · gym_tournament_matches · gym_tournament_match_live | authed | 主辦館幹部 / 報名隊 / 裁判 |
| gym_matches · gym_match_players · gym_match_events | authed | 賽事幹部 / 裁判 / 參賽者 |
| gym_tournament_officials · gym_tournament_invites · gym_tournament_venue_votes | public | 賽事幹部 / 相關隊 |
| arena_tournament_match_officials · arena_tournament_staff · arena_match_forfeits · arena_match_results_log · gym_tournament_arrivals · gym_rep_history | authed | 賽事幹部 / 裁判 |
批 5 · 課程 / 教練金流相鄰,金流部分已鎖
| 表 | 現況 | 提議 |
| coach_courses · coach_enrollments | authed | 教練 / 該館幹部 / 報名學員本人 |
| arena_coach_programs · arena_program_* · arena_course_templates · arena_course_reviews · arena_coach_resumes | authed | 教練本人 / 幹部 |
| coach_bookings | public | 相關人 |
| coach_student_reviews · arena_course_wishes · arena_course_wish_votes | authed | 本人 |
批 6 · 社交 / 系統 / 雜項
| 表 | 現況 | 提議 |
| gym_kudos · gym_match_mvp_votes · gym_chat_messages · gym_session_invites | public | 發話者 / 相關人本人 |
| street_courts | public | 建立者 / 幹部 |
| official_badges · arena_player_sport · arena_player_pass · gym_rating_events | public/authed | server-only(SLP/XP/評級只走 RPC) |
| arena_message_templates · arena_lineups · arena_lineup_templates | public | operator / 建立者 |
| seasons · season_pass_rewards · rule_templates · partner_offers · arena_tutorials · arena_gym_rivalry_events · arena_gym_closures · gym_reports · gym_venue_requests · arena_tournament_feedback · gym_sessions | authed | operator/系統 / 該館幹部 / 相關人 |
| pitch_feedback | anon+authed | 保留 anon(意見回饋合理) |
🟠 剩下:約 10 張「比賽結算表」(要先搬 RPC 才能鎖)
這組表的寫入不是「改自己的資料」,而是比賽結算時在手機端一次改「所有參賽者/兩隊/兩館」的列(評分、戰績、信任分、比分)。所以綁「只能改自己」會把結算打斷 → 必須先把結算邏輯搬進 server 的 SECURITY DEFINER RPC,再把這些表鎖成「只有 server 能寫」。
| 表 | 結算時寫什麼 |
| gym_athletes(評分欄) | 每位參賽者的 rating/勝敗(concludeMatch loop) |
| athlete_season_stats · athlete_trust · athlete_pass_progress | 每位參賽者的賽季戰績/信任分/通行證 XP |
| gym_match_players | 一場比賽兩隊所有上場球員 |
| gym_teams(戰績欄) | 勝隊+敗隊的 rating/勝敗 |
| gyms(Elo 欄)· gym_rating_events · arena_gym_rivalry_events | 館間賽兩館的 Elo/強度/對戰事件 |
| official_badges | 該場裁判/線審的執法場次徽章 |
⚠️ 這是動到正在使用的計分引擎,最高風險,建議獨立一次做(含完整結算流程測試),不跟其他批混。全域排名(arena_player_sport/pass + SLP/XP bump RPC)已在前面鎖好,這組是舊的「單場館」戰績。
後續(比 RLS 更後面)
65 支測試 RPC 目前只擋了 anon,更強的「只限 operator/本人」要逐支加內部檢查。