Lovable 代碼庫審計:安全問題、RLS 差距和公開的 API 金鑰
一個客戶在上個月來找我們,他們有一個 Lovable 生成的應用程式已經在生產環境中運行,並有付費客戶。他們希望我們能添加一些功能並「稍微整理一下」。我們在初始代碼庫審計中發現的情況...頗具啟發性。客戶端代碼中暴露的 API 密鑰。儲存用戶數據的表上缺少行級安全原則。直接的 Supabase 調用,沒有伺服器端驗證。這不是孤立現象——我們現在已經審計了六個不同的 Lovable 項目,模式非常一致。
讓我說清楚:Lovable 是一個令人印象深刻的原型設計工具。它從自然語言提示生成工作 UI 的速度確實令人瞩目。但「能工作的原型」和「生產就緒的應用程式」之間存在巨大差距,這個差距充滿了大多數非技術創始人甚至不知道該尋找的安全漏洞。
本文是我們在多個 Lovable 代碼庫審計中發現的技術分析。如果你用 Lovable 構建了什麼東西,並且你正在獲取真實用戶的金錢或數據,你需要閱讀本文。
目錄
- Lovable 實際生成的是什麼
- API 密鑰問題
- 行級安全:沉默的殺手
- 身份驗證和授權差距
- 客戶端業務邏輯暴露
- Supabase Edge Functions:缺失的部分
- 我們發現的常見漏洞模式
- 如何審計您自己的 Lovable 項目
- 何時重建與何時補救
- 常見問題

Lovable 實際生成的是什麼
Lovable 生成 React 應用程式(通常使用 Vite),配有 Tailwind CSS 和 shadcn/ui 組件,連接到 Supabase 後端。堆棧本身是穩固的——我們在我們的 Next.js 開發工作中也使用這些相同的工具。問題不在於技術選擇。而在於它們如何連接在一起。
這是一個典型的 Lovable 項目結構:
src/
├── components/
│ ├── ui/ # shadcn 組件
│ ├── Dashboard.tsx
│ ├── Settings.tsx
│ └── ...
├── integrations/
│ └── supabase/
│ ├── client.ts # ← 問題從這裡開始
│ └── types.ts
├── pages/
├── hooks/
└── lib/
生成的代碼是清晰可讀的。我為此讚揚 Lovable。但可讀性不等於安全性。該架構做出的決策對演示來說是可以的,但對生產來說是危險的。
讓我們具體一點。
API 密鑰問題
我們審計的每個 Lovable 項目都在客戶端代碼中包含 Supabase 憑證。現在,在 Supabase 擁護者出現之前:是的,anon 密鑰被設計為公開的。Supabase 的文檔明確說明了這一點。anon 密鑰旨在在客戶端代碼中使用,安全應通過行級安全原則來執行。
但醜陋的部分來了。
在我們審計的六個項目中的三個,我們發現 Supabase service_role 密鑰要麼:
- 直接硬編碼在實用程式文件中
- 存儲在提交到 GitHub 倉庫的
.env文件中 - 在可以不進行身份驗證就訪問的 Supabase Edge Function 中被引用
service_role 密鑰繞過所有 RLS 原則。如果有人獲得它,他們對整個數據庫擁有完全的讀寫訪問權限。每個表。每行。每個用戶的數據。
// 我們在一個 Lovable 項目中發現的實際模式(密鑰已隱蔽)
import { createClient } from '@supabase/supabase-js'
// 這在一個名為 lib/admin.ts 的文件中
// 從客戶端組件中導入和使用
const supabaseAdmin = createClient(
'https://xxxxx.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // service_role 密鑰!
)
這不是由 Lovable 直接生成的——它是由創始人添加的,當他們需要管理員功能並要求 Lovable 「添加管理員面板」時。Lovable 遵從了,由於它沒有伺服器端與客戶端安全邊界的概念,它將密鑰放在了方便的位置。
即使只暴露了 anon 密鑰(如預期),如果 RLS 配置不正確,安全模型也會崩潰。這引出了大問題。
行級安全:沉默的殺手
行級安全(RLS)是 Supabase 的主要安全機制,用於在數據庫級別保護數據。正確配置後,無論從客戶端進行什麼 API 調用,都能確保用戶只能訪問自己的數據。
當我們審計六個 Lovable 項目時,我們發現了:
| 項目 | 總表數 | 啟用了 RLS 的表 | 配置正確的 RLS 原則的表 | 暴露的敏感數據 |
|---|---|---|---|---|
| SaaS 儀表板 | 14 | 6 | 3 | 用戶個人信息、計費數據 |
| 電子商務應用程式 | 22 | 10 | 4 | 訂單歷史、地址 |
| 健康追蹤器 | 11 | 4 | 2 | 健康記錄、藥物 |
| 項目管理器 | 18 | 8 | 5 | 客戶數據、文檔 |
| 預訂平台 | 16 | 7 | 3 | 聯繫信息、日程 |
| CRM 工具 | 20 | 9 | 4 | 客戶數據、筆記 |
再看一遍。在健康追蹤器應用程式中——它儲存了實際的藥物和健康信息——只有 2 個表中的 11 個具有正確的 RLS 原則。擁有 anon 密鑰的人(請記住,這是公開的)可以查詢每個用戶的健康記錄。
我們看到的最常見的 RLS 失敗:
完全缺少原則
Lovable 通常創建沒有啟用 RLS 的表。在 Supabase 中,新表上默認禁用 RLS,這意味著任何擁有 anon 密鑰的人都可以讀取所有數據。
-- 我們經常發現的情況:RLS 甚至未啟用
CREATE TABLE public.user_profiles (
id UUID REFERENCES auth.users,
full_name TEXT,
email TEXT,
phone TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 沒有 ALTER TABLE ... ENABLE ROW LEVEL SECURITY;
-- 沒有定義原則
過於寬泛的原則
當 Lovable 確實添加 RLS 時,原則通常太寬泛:
-- 常見的 Lovable 生成原則
CREATE POLICY "Users can view all profiles"
ON public.user_profiles
FOR SELECT
USING (true); -- 這允許任何認證用戶讀取所有配置文件
修復應該是:
-- 應該是什麼樣子
CREATE POLICY "Users can view own profile"
ON public.user_profiles
FOR SELECT
USING (auth.uid() = id);
缺少 DELETE 和 UPDATE 原則
即使 SELECT 原則是正確的,INSERT/UPDATE/DELETE 原則也經常缺失或不正確。我們發現了任何認證用戶都可以更新任何其他用戶配置文件的情況。

身份驗證和授權差距
Lovable 相當合理地處理基本身份驗證——它設置了帶有電子郵件/密碼或社交登錄的 Supabase Auth,登錄/註冊流程通常能正常運作。但身份驗證(你是誰?)和授權(你能做什麼?)是不同的。
授權層幾乎總是不完整或不存在。
考慮一個多租戶 SaaS 應用程式。用戶屬於組織。他們應該只看到來自其組織的數據。他們可能有不同的角色(管理員、成員、查看者)。Lovable 不生成這些中的任何一個。
我們通常發現:
// Lovable 生成的數據獲取
const { data: projects } = await supabase
.from('projects')
.select('*')
// 沒有按 organization_id 過濾
// 沒有檢查用戶的角色或權限
修復需要數據庫級(RLS)和應用程式級的更改。你需要一個 memberships 表將用戶映射到具有角色的組織,檢查成員資格的 RLS 原則,以及進行相應過濾的應用程式代碼。
這是事後很難添加的架構工作。它涉及每個查詢、每個組件、每個頁面。如果你使用 Lovable 構建多租戶 SaaS,這是最會咬你的東西。
客戶端業務邏輯暴露
因為 Lovable 生成純客戶端 React 應用程式,所有業務邏輯都存在於瀏覽器中。這意味著:
- 定價計算在瀏覽器 DevTools 中可見且可操縱
- 功能標誌用於不同的訂閱層次在客戶端檢查
- 折扣代碼和驗證邏輯在 JavaScript 包中
- API 速率限制不存在(沒有伺服器來執行它)
我們在一個 Lovable 生成的 SaaS 中發現了定價層檢查完全是客戶端:
// 在 Lovable 項目的組件中發現
const canAccessFeature = (feature: string) => {
const plan = user?.subscription?.plan
if (plan === 'pro') return true
if (plan === 'basic' && BASIC_FEATURES.includes(feature)) return true
return false
}
用戶可以簡單地在瀏覽器控制台中修改此函數——或直接調用 Supabase API 而不進行此檢查——並在基本計劃上訪問專業功能。數據庫沒有原則強制執行基於計劃的訪問。
這是一個基本的架構問題。業務邏輯需要伺服器端組件。無論是 Next.js API 路由、Supabase Edge Functions 還是單獨的後端服務——某些東西需要驗證用戶無法篡改的操作。
這正是我們經常為生產 SaaS 應用程式推薦 Next.js 或 Astro 之類的框架的原因——它們開箱即用地為你提供伺服器端渲染和 API 路由。
Supabase Edge Functions:缺失的部分
一些 Lovable 項目確實對某些操作使用 Supabase Edge Functions——通常是 Stripe webhook 處理或發送電子郵件。但實現經常有問題:
沒有輸入驗證:Edge Functions 接受並處理發送給它們的任何 JSON,而不驗證形狀、類型或約束。
CORS 配置為允許所有源:
// Lovable Edge Functions 中常見的模式
const corsHeaders = {
'Access-Control-Allow-Origin': '*', // 允許任何網站調用此
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}
沒有身份驗證檢查:該函數不驗證 JWT 令牌,因此未認證的用戶可以調用它。
Stripe webhook 簽名未驗證:在兩個項目中,Stripe webhook 處理程序沒有驗證 webhook 簽名,意味著任何人都可以向端點發送虛假支付事件。
// 我們發現的——沒有簽名驗證
Deno.serve(async (req) => {
const body = await req.json()
// 直接處理事件,不驗證它是否來自 Stripe
if (body.type === 'checkout.session.completed') {
// 更新用戶的訂閱
await supabaseAdmin.from('subscriptions').update({
status: 'active',
plan: 'pro'
}).eq('user_id', body.data.object.metadata.user_id)
}
})
這意味著攻擊者可以向 webhook URL 發送 POST 請求,帶有虛假的 checkout.session.completed 事件,並免費將任何用戶升級到專業計劃。
我們發現的常見漏洞模式
以下是排名最常見問題的摘要,按嚴重性和頻率排列:
| 漏洞 | 嚴重性 | 頻率(共 6 個) | 可利用性 |
|---|---|---|---|
| 敏感表上缺少 RLS | 臨界 | 6/6 | 簡單——只需查詢表 |
| RLS 原則過於寬泛 | 高 | 6/6 | 使用 anon 密鑰很簡單 |
| Service role 密鑰暴露 | 臨界 | 3/6 | 如果發現則微不足道 |
| 沒有 Stripe webhook 驗證 | 高 | 4/6 | 中等——需要端點 URL |
| 僅客戶端授權 | 高 | 6/6 | 使用 DevTools 很簡單 |
| Edge Functions 上沒有輸入驗證 | 中等 | 5/6 | 中等 |
| Edge Functions 上的 CORS 通配符 | 中等 | 5/6 | 簡單 |
| localStorage 中的敏感數據 | 中等 | 4/6 | 物理訪問或 XSS |
| 沒有速率限制 | 中等 | 6/6 | 微不足道 |
| 不安全的直接對象參考 | 高 | 5/6 | 簡單——改變 URL 中的 ID |
如何審計您自己的 Lovable 項目
如果你用 Lovable 構建了正在處理真實用戶數據的東西,以下是如何自己檢查這些問題的方法。
步驟 1:檢查您的 Supabase RLS 狀態
轉到你的 Supabase 儀表板 → 表編輯器。點擊每個表並檢查是否啟用了 RLS。然後轉到身份驗證 → 原則並審查每個原則。
或在 SQL 編輯器中運行此查詢:
SELECT
schemaname,
tablename,
rowsecurity
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename;
如果任何包含用戶數據的表的 rowsecurity 為 false,那就是關鍵問題。
步驟 2:搜索暴露的密鑰
在你的代碼庫中,搜索:
grep -r "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" src/
grep -r "service_role" src/
grep -r "SUPABASE_SERVICE" src/
第一個模式匹配 Supabase JWT 密鑰的開頭。如果你在 src/ 目錄中的任何地方找到 service_role 密鑰,那就是立即關鍵漏洞。
步驟 3:測試 RLS 原則
創建第二個測試用戶帳戶。以該用戶身份登錄並嘗試訪問用戶一的數據。檢查瀏覽器的網絡標籤——你是否收到了你不應該的數據?
你也可以直接用 curl 測試:
curl 'https://YOUR_PROJECT.supabase.co/rest/v1/user_profiles?select=*' \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ANON_KEY"
如果這返回所有用戶配置文件而無需身份驗證,RLS 就壞了。
步驟 4:檢查 Edge Functions
審查每個 Edge Function 以檢查:
- JWT 驗證
- 輸入驗證
- CORS 配置
- Webhook 簽名驗證(適用於 Stripe/支付處理程序)
步驟 5:檢查客戶端包
運行 npm run build 並檢查輸出。搜索構建的 JavaScript 以查找 API 密鑰、業務邏輯和定價數據。包中的任何東西都對用戶可見。
何時重建與何時補救
這是每個 Lovable 創始人一旦意識到這些問題存在就面臨的問題。答案取決於多個因素:
補救如果:
- 你的應用程式少於 10 個表
- 你沒有複雜的授權模型(沒有多租戶、沒有角色)
- 核心架構(數據模型、頁面結構)是健全的
- 你主要需要添加 RLS 原則和將一些邏輯移到伺服器端
重建如果:
- 你需要具有角色和權限的多租戶架構
- 你的業務邏輯複雜且全部在客戶端
- 你需要伺服器端渲染用於 SEO 或性能
- Supabase 架構有重大結構問題
- 你的規模需要適當的基礎設施
對於補救,你通常需要跨所有表添加 RLS 原則、將敏感邏輯遷移到 Edge Functions 或伺服器端層、實現適當的輸入驗證以及添加速率限制。根據複雜性,這是一個 2-4 週的項目對於經驗豐富的開發者。
對於完整重建,我們通常推薦帶有適當關注點分離的無頭架構。雖然初期成本更高,但它為你提供了一個可擴展的基礎。查看我們的定價頁面以了解其外觀。
如果你不確定哪條路是正確的,我們很樂意進行快速評估。在我們的聯繫頁面上聯繫我們。
常見問題
使用 Lovable 進行生產應用程式安全嗎? Lovable 可以生成一個堅實的起點,但輸出需要在投入生產之前進行重大的安全加固。生成的代碼缺少適當的 RLS 原則、伺服器端驗證和授權邏輯。將其視為腳手架,而不是成品建築。在真實用戶信任它處理他們的數據之前,你絕對需要一名開發者審查並保護代碼。
Lovable 會暴露我的 Supabase API 密鑰嗎?
Supabase anon 密鑰是有意公開的——那是通過設計,Supabase 的安全模型通過 RLS 考慮了它。問題是當 Lovable(或你,通過提示)將 service_role 密鑰放在客戶端代碼中時。anon 密鑰公開只有在你的 RLS 原則是防彈的時候才安全,在 Lovable 生成的項目中,它們通常不是。
什麼是行級安全,為什麼它很重要? 行級安全(RLS)是 PostgreSQL 功能,Supabase 使用它來控制用戶可以讀取、插入、更新或刪除哪些行。沒有 RLS,任何擁有你公開 anon 密鑰的人都可以查詢你的整個數據庫——每個用戶的數據,每個私人記錄。它是 Supabase 支持的應用程式中最重要的安全機制,也是 Lovable 項目中最常見的誤配置的東西。
我可以不用開發者自己修復 Lovable 安全問題嗎? 如果你理解 SQL 和 Supabase 的 RLS 原則語法,你可以使用 Supabase 儀表板自己添加基本的 RLS 原則。但是,正確獲取原則——尤其是對於多租戶、共享資源或管理訪問等複雜場景——需要經驗。錯誤的原則可能會將用戶鎖定在自己的數據之外或將所有東西暴露。對於除了簡單個人項目之外的任何東西,請讓專業人士查看它。
我如何檢查我的 Lovable 應用程式的數據庫是否安全?
最快的測試:打開你的瀏覽器的 DevTools,轉到網絡標籤,並查看你的應用程式進行的 Supabase API 調用。複製 apikey 標頭值。然後使用 curl 或 Postman 直接使用該密鑰查詢你的表,不進行身份驗證。如果你取回其他用戶的數據——或任何應為私密的表上的任何數據——你的 RLS 就壞了。
AI 生成代碼中一般最大的安全風險是什麼? AI 代碼生成器優化了使事情工作,而不是使事情安全。他們沒有你威脅形勢的精神模型。最大的風險是:暴露的秘密、缺少輸入驗證、過於寬泛的訪問控制以及缺少伺服器端安全邊界。這些不是 Lovable 獨有的——Cursor、v0、Bolt 和其他 AI 工具生成的代碼中存在類似問題。不同之處在於 Lovable 生成人們直接部署到生產環境的完整應用程式。
使用 Lovable 後我應該從 Supabase 切換到不同的後端嗎? Supabase 本身很好。它是一個具有適當安全能力的穩固平台。問題是 Lovable 如何配置它。你不需要放棄 Supabase——你需要正確配置 RLS 原則、將敏感操作移到 Edge Functions,並添加 Lovable 跳過的授權層。基礎設施很好;配置只需要工作。
修復 Lovable 生成的應用程式中的安全問題需要花費多少? 對於直接的補救——添加 RLS 原則、保護 Edge Functions、移除暴露的密鑰、添加基本輸入驗證——根據表的數量和授權模型的複雜性,你看起來大約 $3,000-$8,000。完整的重建與適當的架構運行 $15,000-$50,000+ 取決於範圍。補救路徑幾乎總是更具成本效益,如果你的核心數據模型是合理的。