AI 建立應用程式的安全清單:上線前應檢查什麼
在真實用戶使用你用 AI 建立的應用程式之前,請檢查以下七件事:每個頁面及 API 都要確認用戶的身分及其可以做什麼;機密金鑰只存放在伺服器,絕不放在瀏覽器或對話中;所有輸入都要在伺服器端驗證;每位用戶只能存取自己的紀錄;登入及高成本的端點須設有速率限制;依賴項目保持最新;如果出現問題,你亦能還原資料。以下清單把每一項都轉化為具體的測試,讓你無需閱讀程式碼也能執行。
AI 應用程式建立工具擅長令功能運作,但它們不會自動變得謹慎,因為「謹慎」很少出現在提示之中。下文大部分問題都源於沒有人要求的事項,因此解決方法通常就是提出要求。
如何使用這份清單
請按順序逐項處理,每項都要做兩件事:要求 AI 確保已妥善處理,以及自行測試。AI 可以撰寫權限檢查,但只有測試才能證明它確實有效。各項目以以下方式標示:
- 必須:在任何其他人使用應用程式之前完成。
- 應該:在你擁有真實用戶或真實資料之前完成。
- 稍後:隨著應用程式發展再處理即可。
如果你只有一小時,請完成所有必須項目。
1. 身分驗證:此人是誰?
身分驗證是確認某人的身分,通常透過登入進行。基本概念請參閱什麼是身分驗證,登入的選項則請參閱如何為應用程式加入登入功能。
- **必須:**每個顯示私人資料的頁面都要求登入。測試方法:登出後,直接在瀏覽器貼上私人頁面的網址。
- **必須:**這些頁面背後的每個 API 端點也要求登入,而不只是頁面本身。測試方法:登出後,打開瀏覽器的網絡分頁,重新發送你登入時應用程式所發出的請求。
- **必須:**密碼以慢速的密碼雜湊演算法儲存,絕不以明文儲存。OWASP 的密碼儲存指引首推 Argon2id,其次是 scrypt、bcrypt 或 PBKDF2。請詢問:「密碼是如何儲存的?」
- **應該:**密碼重設連結會過期,且只能使用一次。
- **應該:**工作階段 Cookie 標示為
Secure、HttpOnly及SameSite,而登出後會在伺服器端結束工作階段。 - **稍後:**提供雙重驗證,或透過已支援此功能的供應商登入。
檢查每一個會回傳用戶資料的 API 路由及頁面。每一個都必須在伺服器端拒絕未登入用戶的請求,而不只是在頁面程式碼中處理。列出你已檢查的路由。
2. 授權:他們獲准做什麼?
授權是登入之後的步驟:決定此特定用戶可以查看及更改什麼。AI 建立的應用程式最常在這裡出現嚴重漏洞,因為應用程式看起來正確,每位用戶的儀表板只顯示其自己的資料,但只要有人直接提出要求,伺服器就會毫不猶豫地交出任何人的資料。
- **必須:**每一次讀取、更新及刪除,都要在伺服器端確認該紀錄屬於目前用戶(或其團隊)。
- **必須:**進行測試:建立兩個帳戶 A 及 B。以 A 的身分打開 A 的某項紀錄,並記下網址或網絡請求中的 ID。然後以 B 的身分登入,並要求同一個 ID。B 必須收到錯誤,而不是 A 的資料。
- **必須:**管理員頁面及管理員 API 端點,都要在伺服器端檢查用戶的角色。隱藏管理員連結並不等於保護。
- **必須:**用戶不能透過編輯請求來更改自己的角色、價格、餘額或擁有者欄位。測試方法:在網絡分頁中查看更新個人資料時發送的內容。如果當中包括
role或isAdmin之類的欄位,請要求 AI 忽略來自客戶端的這些欄位。 - **應該:**網址中的 ID 難以猜測(使用隨機 ID,而非 1、2、3)。這不能取代權限檢查,但在缺少權限檢查時可以減少損害。
對每一個讀取或更改紀錄的端點,都要在伺服器端確認已登入的用戶擁有該紀錄,或獲准存取它。如果沒有,就回傳 404。然後向我展示你會如何以兩個帳戶進行此測試。
3. 資料庫中的資料列存取控制
「資料列存取控制」是指資料表中的每一行(一個預約、一張發票)只會對其所屬的用戶可見。常見的實現方式有兩種:
| 方式 | 運作方式 | 需要留意 |
|---|---|---|
| 在伺服器程式碼中 | 每個查詢都包含一個篩選條件,例如「擁有者為目前用戶」 | 一個遺漏的篩選條件就會令所有資料外洩 |
| 在資料庫中(例如 Postgres 資料列層級安全) | 資料庫本身會拒絕用戶無權查看的資料列 | 設定較多;伺服器必須以正確的用戶身分連接 |
兩種方式都可以做得妥善。重點是:
- **必須:**如果瀏覽器會直接與資料庫溝通(部分託管資料庫產品允許這樣做),則每個資料表都要啟用資料列層級規則。否則,任何持有公開金鑰的人都可以讀取整個資料表。
- **必須:**查詢應以目前用戶或團隊作篩選,而不是以瀏覽器傳來的 ID 作篩選。
- **應該:**共用資料(例如團隊的專案)要有清楚的規則,說明誰屬於該團隊,並且只在一處執行。
4. 機密資料及 API 金鑰
API 金鑰就是服務的密碼。Stripe、電郵及 AI 供應商都會使用金鑰。背景資料請參閱什麼是環境變數及機密資料。
- **必須:**金鑰儲存在專案的環境變數或機密設定中,絕不寫入程式碼。
- **必須:**可以消費金錢或讀取私人資料的金鑰,只在伺服器端使用。測試方法:打開正式網站,在開發人員工具中查看頁面原始碼及 JavaScript 檔案,並搜尋你金鑰的開頭部分(例如
sk_)。它不應出現。 - 必須:金鑰從未貼入對話、公開儲存庫或截圖之中。如果曾經如此,請在供應商處輪換金鑰(建立新的,並刪除舊的)。
- **應該:**如果供應商提供受限或限定範圍的金鑰,請使用它。例如,Stripe 建議使用受限金鑰,且只授予整合所需的權限。
- **應該:**測試金鑰與正式金鑰分開,並且只在準備好時,正式應用程式才使用正式金鑰。
部分金鑰設計上就是公開的,例如 Stripe 的可公開金鑰(pk_…),或只限你的網域使用的地圖金鑰。這條規則針對的是那些能授予權力的金鑰,而不是所有看似金鑰的字串。
5. 輸入驗證
用戶傳送的任何內容(表格欄位、檔案上傳、網址參數)都可能是任何東西,而不只是表格所允許的內容。
- **必須:**驗證在伺服器端進行,而不只是在瀏覽器中。瀏覽器的檢查只為方便而設,任何人都可以略過。
- **必須:**資料庫查詢使用參數,而不是把用戶輸入的文字拼接在一起(這可以防止 SQL 注入)。請要求 AI 確認。
- **必須:**用戶輸入的文字以純文字顯示,而不是當作 HTML 執行。測試方法:把
<b>hello</b>輸入為你的名稱。你應該看到標籤本身,而不是粗體文字。 - **應該:**檔案上傳要檢查類型及大小,而且上傳的檔案不應從應用程式的主網域以可執行的頁面形式提供。
- **應該:**向用戶顯示的錯誤訊息應簡單明瞭(「發生錯誤」);詳細的錯誤只記錄在伺服器日誌中。
- **應該:**來自 Stripe 等服務的 Webhook 在執行前,要先驗證供應商的簽署。請參閱什麼是 Webhook。
為每個表格及 API 端點加入伺服器端驗證:必填欄位、長度、格式及允許的值。其他一律拒絕,並提供清楚的訊息。不要向用戶顯示內部錯誤細節。
6. 速率限制及濫用
速率限制是限制某人在一段時間內可以發出的請求數量。若沒有它,任何人都可以整天嘗試猜測密碼、大量提交你的註冊表格,或令你的付費 API 費用急升。
- **必須:**登入、註冊及密碼重設,都要按 IP 位址及按帳戶設定速率限制。
- **必須:**任何每次呼叫都會令你付出費用的功能(AI 模型請求、短訊、電郵),都要有每位用戶的限額,並要求登入。
- **應該:**公開表格(聯絡表格、候補名單)要有防垃圾訊息保護:速率限制、隱藏的誘餌欄位,或 CAPTCHA。
- **應該:**在付費供應商處設定消費上限或提醒,這樣即使出現程式錯誤或遭到攻擊,也不會產生無上限的帳單。
7. 依賴項目
應用程式是由開放原始碼套件組成的,而套件有時會有已知的漏洞。
- **應該:**要求 AI 檢查已知漏洞(對於 JavaScript 專案,使用
npm audit或你的套件管理工具的同等指令),並更新受影響的部分。 - **應該:**移除應用程式已不再使用的套件。
- **應該:**對使用者很少的套件保持戒心,也要留意名稱看似是熱門套件拼錯的套件。
- **稍後:**每一兩個月重新檢查一次;如果你的程式碼放在 GitHub,可以開啟自動提醒。
8. 備份及復原
安全也包括能夠從錯誤中復原,無論錯誤來自你、AI,還是攻擊者。
- **必須:**清楚知道你的資料存放在哪裡,以及是否有備份。不要假設,請查閱你的主機的說明文件。
- **應該:**定期匯出重要資料並自行保存(例如使用 CSV 匯出功能或資料庫傾印),並存放在另一個獨立的位置。
- **應該:**將你的程式碼保存在版本控制中,以便還原任何版本。
- **應該:**刪除性操作(刪除帳戶、刪除專案)要求確認,並考慮採用可於一段時間內復原的「軟刪除」。
- **稍後:**實際測試一次還原。從未還原過的備份只是一個希望,而不是計劃。
9. 上線前
- **必須:**正式網站全面使用 HTTPS。
- **必須:**移除開發時遺留的範例資料、測試帳戶及除錯頁面。
- **應該:**私隱政策須列明你收集哪些資料及其原因。如果你收集個人資料,許多地方都要求提供此政策。切勿聲稱擁有你並未取得的認證(SOC 2、HIPAA)。
- **應該:**設有一個讓人可以聯絡你回報安全問題的途徑,並知道如何迅速輪換所有金鑰。
如果需要在安全以外進行更全面的上線前檢查,請參閱如何將 AI 原型推向正式營運。
何時需要專業審閱
清單能發現常見錯誤,但不能取代專家。如果你是自行處理信用卡號碼(而非透過託管的結帳頁面),或儲存健康、財務或兒童資料,或向會要求安全問卷的公司銷售,或一旦外洩會造成嚴重損害,就應考慮付費進行審閱。若你的程式碼可以匯出,審閱會容易得多。
在 Mythex 上建立時的安全事項
Mythex 並不包括安全掃描面板,因此上述清單就是你應依循的流程。以下幾點可能有幫助:
- **專案機密資料。**將金鑰儲存於專案設定 → 機密資料之下,或透過代理在對話中顯示的機密資料卡儲存,令金鑰不會出現在程式碼及訊息之中。更改正式應用程式的機密資料後,請重新發布。
- **計劃模式及詢問模式。**要求代理在不編輯的情況下檢視權限:「在詢問模式下,列出每個 API 路由及其執行的權限檢查。」
/test可讓代理以用戶身分在你的預覽中逐步操作,適合用於第 2 節的雙帳戶測試。- 檢查點讓你可以還原令某項功能損壞的更改。
請參閱說明文件中的你所建立應用程式的安全性及環境變數及機密資料。如果你接下來要加入用戶帳戶,請閱讀如何為應用程式加入登入功能。
常見問題
用 AI 建立的應用程式安全性會較低嗎?
本身不一定。不過 AI 建立工具的重點是令功能運作,而沒有人要求時,安全檢查很容易被忽略。最常見的漏洞是伺服器缺少權限檢查,以及 API 金鑰放在瀏覽器可以讀取的位置。
對 AI 建立的應用程式而言,最重要的安全檢查是什麼?
以一位用戶登入,然後嘗試透過應用程式的頁面,或在網址中更改 ID,去查看或更改另一位用戶的資料。這類存取控制失效的問題,在 OWASP Top 10:2025 網頁應用程式安全風險清單中排名第一。
AI 建立的應用程式應該把 API 金鑰放在哪裡?
放在專案的環境變數或機密設定中,並且只供伺服器端程式碼使用。可以消費金錢或讀取私人資料的金鑰,絕不應出現在瀏覽器的程式碼、對話中,或 Git 儲存庫內。
上線前需要進行安全審核嗎?
如果是一個資料風險較低的小型應用程式,按照這類清單逐項檢查已是合理的起點。但如果你直接處理付款、健康、財務或兒童資料,或有合約上的安全要求,就應該請合資格的人士審閱。