#standards#security#lessons#auth#multi-tenant#bugs
บทเรียนบั๊กสิทธิ์และการข้ามฐานข้อมูล
รวมบั๊กที่ตรวจพบและแก้แล้วในรอบ 2026-10-24 (branch dev) ด้านการยืนยันตัวตน การแบ่งสิทธิ์ และการแยกฐานข้อมูล พร้อมกฎที่ต้องจำ เช็กลิสต์ใช้งานจริงอยู่ที่ เช็กลิสต์ความปลอดภัย API: ตัวตน สิทธิ์ และช่องโหว่เว็บ (Secure API Checklist)
บั๊ก → วิธีแก้ → กฎที่ต้องจำ
| รหัส | อาการ | วิธีแก้ | กฎ |
|---|---|---|---|
| S1 | Google login เชื่อตัวตนจาก body (ไม่ตรวจ idToken) |
บังคับ idToken, ตรวจ aud และ email_verified |
ตัวตนต้องมาจากข้อมูลที่ตรวจแล้ว ห้ามเชื่อ body |
| S2 | route ที่เรียก backend ด้วยกุญแจ Admin ตรวจแค่มี session | isWorkspaceAdmin() ตรวจว่าเป็น Admin ของฐานนั้นจริง (Demo ถูกปฏิเสธ) |
route ที่ใช้กุญแจ Admin ต้องตรวจ Admin ฝั่ง server |
| B1 | ทางเขียนจากเบราว์เซอร์บางทางไม่ผ่านนโยบาย write lockdown | ใช้ ValidateClientInsert() ตัวเดียวกับ /query/exec |
ทุกทางเขียนจากเบราว์เซอร์ใช้นโยบายเดียวกัน |
| B2 | route ที่ไม่ต้อง login ให้ผู้เรียกเลือกฐานข้อมูลบริษัทเองได้ | ผู้ไม่ login ถูกตรึงที่ bcdemo |
ห้ามให้ผู้เรียกเลือก tenant เองเมื่อไม่ยืนยันตัวตน |
รอบที่ 2: เสริมเกราะ Auth/API
getAdminApiKey()ไม่ส่งกุญแจ dev ใน production (ตอบ 503NO_ADMIN_API_KEY)- Google OAuth redirect มี
state(cookie +timingSafeEqual) กัน login CSRF /api/auth/databasesตรวจว่าฐานข้อมูลอยู่ในavailableCompaniesของผู้ใช้/api/admin/*ใช้requireSystemAdmin()(ต้องsession.mode === "admin");/api/fraudwarning|workmonitorต้องมี session;/api/monitormap/tilePOST ต้อง login และ single-flightPOST /api/workspace/databasesใช้session.emailเท่านั้น (ไม่รับอีเมลจาก client)
รอบที่ 3 และการตัดสินใจของลุงจืด (2026-10-24)
- สิทธิ์จอแยกต่อฐานข้อมูล: เพิ่มคอลัมน์
database_nameในbc_permissions_user/bc_permissions_group; Backend บังคับสิทธิ์ Add/Edit/Delete บน/process/*(doc/save,stocktools/pointdocsave,stocktools/stockbeginningsave),/query/exec,/query/execBatch,/blob/insert; ฝั่งหน้าจอผูกuseScreenRights()ทุกจอ (เดิมTabsContext.screenRightsบังคับแค่ฝั่งหน้าจอ backend ต้องตรวจซ้ำเสมอ) — ไฟล์ที่เกี่ยวข้องadmin/menu_permissions.go,admin/workspace_google.go - โหมดสาธิตดูระบบส่วนกลางได้แต่ห้ามเพิ่ม/แก้ไข/ลบ:
isDemoCentralViewer()(ปุ่ม Demo, โดเมนสาธิต, บัญชีสาธารณะของbcdemo); GET ใช้requireSystemAdminView()+ ล็อก providerbcdemo+ ตัดฟิลด์ลับ (demoSafe); เขียนทุกชนิดได้ 403DEMO_READ_ONLY; โซน/adminมีแถบ "ดูอย่างเดียว" - Login ผู้ดูแลส่วนกลาง (
mode: "admin") แยกจากปุ่ม Google และปฏิเสธบัญชีสาธิต (DEMO_ADMIN_FORBIDDEN); เปลี่ยนรหัสผ่านตัวเอง ผ่าน/api/auth/change-passwordตรวจรหัสเดิมก่อน (บัญชี Google ให้ไปเปลี่ยนที่ Google)
ที่มา
docs/kms/KMS_SECURITY_DATA_INTEGRITY_LESSONS.mdตาราง S1–S2, B1–B2, รอบที่ 2–3, "การตัดสินใจของลุงจืด" ข้อ 1, 3- ตรวจแล้วมีจริง:
frontend/src/app/api/workspace/[...path],frontend/src/app/api/auth/change-password/route.ts,backend/.../admin/menu_permissions.go,blob/handler.go
ดูเพิ่ม
สารบัญมาตรฐานและกฎเหล็กของ BC Ai Account (Standards Overview) · เช็กลิสต์ความปลอดภัย API: ตัวตน สิทธิ์ และช่องโหว่เว็บ (Secure API Checklist) · Google Login, Multi-Tenant PDPA และหน้าเลือกโมดูลหลัง Login (Google OAuth, Tenant Isolation, Home Hub) · ความถูกต้องของข้อมูล: เงิน ภาษี Transaction เดียว และ Rebuild (Data Integrity, big.Rat, ExecBatch) · ภาพรวม Backend Go ของ BC Ai Account (Backend overview)