// docs / security guides / pre-launch SaaS
SaaS 上線前安全檢查清單:35+ 項
您只需幾天即可推出使用 Cursor、Claude Code、Lovable 或 Bolt 建立的 SaaS 產品。該清單是一項 go/no-go 審計,涵蓋了 AI 工具經常忽略的安全表面,以及快速發貨的創始人在拿走客戶資金之前需要解決的安全問題。八個部分,超過 35 個項目,每個部分可在 30-90 分鐘內解決。列印它,劃掉它,自信地部署。
以下的每一項都是必不可少的。綠色表示已發貨並已驗證;紅色表示未解決並阻止啟動。有關每個類別的詳細演練(包含程式碼片段和實際故障模式),請參閱How to secure an app built with AI coding tools 和The vibe coding security checklist。
客戶資料隔離
在多租戶 SaaS 中,第一個安全邊界是資料隔離。每個客戶的資料必須無法被其他客戶訪問,這是在資料庫層而不是應用程式層強制執行的。
- 使用
ALTER TABLE public.table_name ENABLE ROW LEVEL SECURITY; ALTER TABLE public.table_name FORCE ROW LEVEL SECURITY;在每個Supabase 表上啟用行級安全性(RLS)。 FORCE 防止表所有者繞過它。 - 對於每個 RLS 策略,驗證經過驗證的使用者或組織的謂詞範圍。範例:
CREATE POLICY "users_see_own" ON public.items FOR SELECT USING (auth.uid() = user_id);。使用第二個使用者帳戶進行測試以確認資料保持隔離。 - 如果使用 Firebase / Firestore,規則必須與您的租用戶型號相符。不要使用
allow read, write: if true;或有時間限制的測試規則。使用allow read, write: if request.auth.uid == resource.data.owner_uid;或等效的組織範圍匹配。 - 使用簽名 URL 或短期令牌進行文件訪問,切勿使用公共儲存桶。 Supabase 儲存:在
objects表格上設定ENABLE ROW LEVEL SECURITY,並制定將檔案存取範圍限制為經過驗證的使用者的策略。以不同使用者測試下載。 - 在 API 層上,每個請求都必須包含
auth.uid()或 org-id 上下文。每個資料庫查詢都必須按該上下文進行過濾。例:沒有SELECT * FROM items WHERE id = $1;總是SELECT * FROM items WHERE id = $1 AND user_id = auth.uid()。
計費和付款
Stripe 整合是客戶信任與財務安全的結合。這裡的配置錯誤意味著付款被盜、退款循環或收入損失。
- 在生產中使用live Stripe keys。在登臺時使用單獨的測試模式鍵進行測試。在沒有最終即時模式掃描的情況下,切勿將開關從測試切換到即時。
- 驗證每個入站事件的 Webhook 簽章:
const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);。如果簽名失敗則拋出。僅將 Webhook 機密儲存在環境變數中,而不是儲存在程式碼中。 - 使用以
event.id為鍵的資料庫表在 Webhook 處理程序上實現冪等性。如果同一個 Webhook 到達兩次(它會),則第二次運行是無操作。將冪等行寫入與狀態變更相同的交易中。 - 在
customer.subscription.updated和customer.subscription.deleted上,立即撤銷存取權限。不要等待 cron。透過在Stripe儀表板中取消訂閱並驗證使用者在 5 秒內被鎖定來進行測試。 - 僅將Stripe 客戶ID 和訂閱ID 儲存在您的資料庫中,切勿儲存完整的卡片或API 金鑰。在每個驗證邊界上從 Stripe 擷取即時訂閱狀態(頁面載入、API 呼叫、cron 檢查)。不要快取訂閱狀態超過 1 分鐘。
身份驗證和會話
Auth 是 SaaS 中的二階攻擊目標。使用者帳戶是資料和支付方式的載體。
- 在每條受保護的路由上使用
supabase.auth.getUser(),切勿使用getSession()。getSession()讀取未經驗證的cookie;getUser()驗證JWT 伺服器端。在 Next.js 中:在提供受保護的內容之前const { data: { user } } = await supabase.auth.getUser();。 - 在身份驗證 cookie 上設定
SameSite=Lax(Supabase 身份驗證預設執行此操作)。在 DevTools → 應用程式 → Cookies 中驗證。如果您看到SameSite=None,請將sameSite: 'Lax'新增至您的會話配置。 - 在您自己的管理員帳戶上啟用MFA。對於使用者導向的MFA,在啟動之前對其進行端對端測試:註冊、註冊TOTP 裝置、登出、使用TOTP 令牌重新登入、驗證其是否有效。
- Magic-link 令牌必須在 15 分鐘內過期。密碼重設令牌必須在 1 小時內過期。會話令牌 (JWTs) 的壽命可以更長 (24h-7d),但每次使用時都必須驗證。檢查您的身份驗證提供者的預設設定。
- 測試註銷完整性:使用者點擊登出後,瀏覽器刪除身份驗證會話,伺服器撤銷任何令牌,並且使用者無法存取受保護的頁面。在Supabase 中:呼叫
await supabase.auth.signOut()並驗證JWT 在下一個請求中不再有效。
PII 和合規性
如果您收集電子郵件、姓名、付款資訊或任何PII,您就有法律義務:資料最小化、安全儲存、按需刪除和DPA 準備。
- 編寫並發布隱私權政策(不是可選的,即使對於獨立 SaaS 也是如此)。說明您收集哪些資料、原因、保留時間以及使用者權利(存取、更正、刪除)。使用 Termly 或類似的模板,但可以對其進行自訂。
- 實作一個刪除帳戶API端點,從資料庫中清除PII。測試它:建立帳戶,添加數據,刪除帳戶,驗證資料是否消失(使用直接資料庫檢查)。
- 為了確保 GDPR / CCPA 合規性,請在 30 天內回覆資料主體請求(存取/更正/刪除)。記錄您的流程。如果您的應用程式是基於 EU- 或為 EU 使用者提供服務,則需要包含 Stripe、Supabase 和任何處理器的資料Processing 附錄 (DPA)。
- 加密靜態敏感欄位(密碼由您的身分驗證提供者進行雜湊處理;但信用卡標記化、API 金鑰、機密應使用
pgcrypto或外部保管庫)。切勿儲存純文字信用卡號(請使用 Stripe 標記化取代)。
營運準備狀況
安全是持續的。事件回應、監控和操作手冊在第一天之前就開始了。
- 設定狀態頁面(Statuspage.io、Uptime Robot 或簡單的 index.html)。客戶需要知道是否有停電。更新每個事件。
- 記錄並測試隨叫隨到的輪換。誰會在凌晨 2 點的警報中醒來?誰有部署密鑰?誰可以撤銷受損的令牌?記錄下來並在啟動前進行防火演習。
- 編寫安全事件回應操作手冊:如果客戶報告違規、遺失金鑰、服務中斷,該怎麼辦。將其分發給您的團隊。測試一種場景(e.g.,模擬密鑰洩漏)以驗證該計劃是否有效。
- 備份和復原過程必須經過測試,而不是理論。可以從備份中復原嗎?計時吧。 Supabase:啟用自動備份(免費保留 7 天,付費保留 30 天)。每季測試一次到單獨專案的恢復。
- 為特權操作啟用審核日誌記錄:Stripe 儀表板登入、Supabase 管理API 呼叫、資料庫架構變更、付款對帳。工具:CloudTrail (AWS)、Supabase 審核日誌、PostgreSQL
pgaudit擴充。
外部攻擊面
您的API 邊界不斷受到攻擊者掃描。在惡意流量襲來之前將其鎖定。
- 對每個公共端點進行速率限制。範例:註冊時每個 IP 每分鐘 100 個請求,密碼重設時每分鐘 10 個請求。使用 Vercel KV、Redis 或類似的。失敗並返回 429(請求過多)。
- 將 CAPTCHA(hCaptcha 或 reCAPTCHA)新增至註冊和密碼重設端點以擊敗機器人。在接受請求之前驗證伺服器端的令牌。
- 如果可用,請使用WAF(Web 應用程式防火牆):Cloudflare、Vercel Web 應用程式防火牆或AWS WAF。自動封鎖已知的惡意 IP 和模式。
- 掃描開放的API端點。每月對您的生產域執行一次被動 FixVibe 掃描。檢查暴露的調試路徑、GraphQL 內省、API 金鑰洩漏或配置暴露的結果。
- 每季輪換一次憑證(API 金鑰、OAuth 令牌、資料庫密碼)。記錄輪換過程並在可能的情況下將其自動化。
可觀察性和記錄
當出現問題時,日誌就是您的取證記錄。從第一天開始就設定它們。
- 將日誌:Supabase 日誌、Vercel 日誌、應用程式日誌和驗證日誌集中到單一儀表板(Datadog、LogRocket 或自架ELK)。可搜索,保留至少 90 天。
- 安全事件警報:重複登入失敗(可能是帳號被接管)、異常API 使用(可能是抓取)、錯誤高峰(可能是攻擊或合法事件)。設定閾值和 Slack 整合。
- 為每個特權操作發出審核日誌:使用者角色變更、新管理員帳戶建立、付款方式新增、API 金鑰中的範圍變更。將它們與應用程式日誌分開存儲,並保留不可變的保留。
最終驗證
在宣布之前,請執行完整的 FixVibe 掃描並以安全眼光審查結果。
- 針對您的生產域執行 FixVibe Pro 主動掃描。配置您的網域以進行主動測試(DNS TXT 或 HTTP 檔案驗證)。授權掃描並審查每項發現——特別是關鍵和嚴重性高的發現。明確修復或接受每一項。
- 啟用計劃的重新掃描:Pro 計劃 → 3 小時、6 小時、12 小時或每天。 Unlimited 方案 → 6 小時、12 小時、每天、每 2 天或每週。與 active IDOR walking、SQL injection 和 reflected XSS 檢查您已驗證的網域配對。
- 設定網路鉤子:將FixVibe連接到Slack或電子郵件,以便關鍵發現即時觸發警報。請參閱/docs/webhooks進行設定。
- 進行最終的手動代碼審查,重點關注 /docs/security-guides/ai-generated-code-security-scanner 中的陷阱:捆綁包中的秘密、RLS/rules、身份驗證邊界、CSP、中間件放置。使用vibe coding security checklist作為審核範本。
發售日
您已清除清單。充滿信心地部署。啟動後,積極監控:第一週每天檢查FixVibe結果,1小時內回應警報,並保持掃描計畫運作。有關包含程式碼片段的逐步強化指南,請參閱How to secure an app built with AI coding tools。
