用 Prompt 守住資安:檢查清單與 AI Code Review
上一課看完那些帳單爆炸、資料庫被整包下載的案例,你大概有點睡不著:我的網站也是 AI 寫的,那些洞我有沒有?但打開程式碼一看,滿螢幕看不懂的東西——不會讀程式碼的人,到底要怎麼檢查?
答案其實很直白:讓 AI 檢查 AI。會挖出這些洞的知識,AI 本來就有,它只是在你沒要求的時候不會主動幫你想。差別在問法:丟一句「幫我檢查安全性」,你會得到一頁四平八穩的空話;換成這堂課給你的具體 prompt——指定掃什麼、去哪掃、輸出什麼格式——它就會變成一個相當稱職的資安審查員。這堂課全是可以直接複製的模板,抄走就能用。
這堂學什麼
- 三道防線的觀念:生成時防、開發中掃、上線前守門,而不是上線前才臨時抱佛腳
- CLAUDE.md 資安班規:一段可複製的規則,讓 AI 從源頭就不寫出洞
- 三大掃描 prompt 模板:掃 secrets、掃輸入驗證、掃權限,附完整可複製版本
- .env 與 .gitignore 實戰:設定加驗證,確認機密真的沒進 git
- 上線前 AI code review 六步流程 + key 洩漏的輪替急救 SOP
- 免費工具:GitHub secret scanning、push protection、gitleaks 怎麼疊著用
觀念:資安是三道防線,不是一次檢查
先建立一個心智模型。很多人以為資安檢查是「上線前跑一次掃描」,但那是最貴的做法:洞已經寫出來、可能已經跟其他程式碼糾纏在一起,拆的成本最高。正確的打法是三道防線:

第一道在生成時:把資安規則寫進 CLAUDE.md,AI 每次動手都自動遵守,洞根本不會被寫出來,成本趨近零。第二道在開發中:每做完一個功能,花一分鐘跑掃描 prompt,那時 context 還熱著,AI 修得又快又準。第三道在上線前:開新對話做全面 review,再讓 GitHub 的自動掃描當最後一張網。三道都便宜,但疊起來能擋掉第 6 課講的絕大多數災難。
第一道防線:把資安班規寫進 CLAUDE.md
第 5 課教過 CLAUDE.md 是 AI 的「班規」,每次開新對話自動載入。當時寫的是風格與流程規則,現在把資安規則補進去。打開專案根目錄的 CLAUDE.md,加上這段:
## 資安規則(每次都必須遵守)
- 任何 API key、密碼、token 一律用環境變數(process.env),
絕對不寫死在程式碼裡。需要新的環境變數時,先提醒我加到
.env 和 Vercel,並同步更新 .env.example(值留空)。
- 所有 API route 必須在後端驗證每一個輸入欄位(型別、範圍、
長度),不合法回 400。前端驗證只是輔助,不算數。
- 任何會讀寫資料的 API,開頭必須先驗證使用者身分與權限;
查詢個人資料時必須確認「這筆資料屬於當前使用者」。
- 呼叫第三方 API(OpenAI 等)一律經過自己的後端,
不在前端直接呼叫。
- 禁止使用 dangerouslySetInnerHTML、eval、
以字串拼接的資料庫查詢。真的必要時,先停下來說明原因
並等我同意。
- Next.js 環境變數禁止用 NEXT_PUBLIC_ 前綴存放任何機密。
逐條說明這在防什麼:第一條防 key 寫死(第 6 課的帳單爆炸案);第二、三條防「信了前端」和「沒驗身分」這兩個 AI 最常犯的邏輯洞;第四條把 key 永遠留在後端;第五條直接禁用幾個高危寫法——AI 圖方便時很愛用它們;最後一條防 Next.js 特有的地雷(下面會講)。
第二道防線:三大掃描 prompt 模板
班規防新程式碼,但已經寫出來的舊程式碼呢?用掃描 prompt。三段模板分別對付第 6 課的三類洞:

模板一:掃 secrets
掃描整個專案(包含所有設定檔),找出所有寫死在程式碼裡的機密:
API key、密碼、token、資料庫連線字串。同時檢查:
1. .env 是否在 .gitignore 裡?用 git 指令實際驗證,不要用猜的。
2. git 追蹤的檔案裡有沒有 .env 或其他含機密的檔案?
3. 有沒有機密曾經被 commit 進 git 歷史?
以表格輸出:檔案:行號|機密類型|風險等級|建議修法。
如果全部乾淨,明確說「未發現」。
模板二:掃輸入驗證
列出這個專案所有「接收使用者輸入」的入口:表單、API route、
網址參數。逐一檢查:後端有沒有重新驗證每個欄位的型別、範圍、
長度、格式?有沒有把使用者輸入直接拼進資料庫查詢或 HTML?
只在前端驗證的一律視為未驗證。
以表格輸出:入口|缺什麼驗證|攻擊者可以做什麼|風險等級|修法。
模板三:掃權限
以攻擊者的視角檢查這個專案的每一個 API route 和頁面:
1. 哪些入口沒有驗證登入身分?
2. 哪些入口驗了登入、但沒驗「這筆資料是否屬於當前使用者」?
(例如把網址裡的 id 改成別人的,能不能看到別人的資料?)
3. 管理功能是否只靠前端隱藏按鈕或跳轉來「保護」?
以表格輸出:入口|問題|攻擊情境|風險等級|修法。
三段模板有共同的設計:指定範圍(整個專案、所有入口),AI 才不會只看眼前的檔案;要求檔名加行號,你才能逐條追蹤有沒有修;要求風險等級,你才知道先修哪個;要求「沒發現就明講」,避免它為了交差硬掰幾條不痛不癢的建議。掃出來的高風險項目,直接接一句:
從高風險開始,一次修一項。每修完一項就停下來,
告訴我改了哪個檔案、為什麼這樣改,等我確認再修下一項。
一次修一項是第 5 課的老規矩:改壞了才知道是哪一步壞的,退得回去。
實戰:.env 與 .gitignore 一次設對
secrets 類問題的地基就是這兩個檔案,值得專門走一遍。先看懂角色分工:

確認 .gitignore 有擋 .env
打開專案根目錄的.gitignore,確認有這幾行(沒有就補上):.env
.env.local
.env*.local
用指令驗證,不要用猜的
在終端機跑:git check-ignore -v .env
有輸出(顯示是哪一行規則擋住它)代表 .env 確實被忽略;沒有任何輸出就是沒擋住,回步驟 1 檢查。再跑一個雙保險,列出 git 實際追蹤的檔案裡有沒有 env:
git ls-files | grep env
理想結果是只看到 .env.example。如果看到 .env 本人,代表它已經被 commit 過——直接跳到下面「常見坑 1」處理。
建立 .env.example
複製一份 .env、把所有值清空,存成.env.example:OPENAI_API_KEY=
RESEND_API_KEY=
這個檔案沒有機密、可以進 git。它的用途是「需求清單」:未來的你、或幫你 clone 專案的 AI,一看就知道要準備哪些 key。
正式站的 key 填在 Vercel
.env 不會被部署上去。到 Vercel 專案的 Settings → Environment Variables 把同樣的 key 填一遍,然後 Redeploy(環境變數改了不重新部署不會生效)。第三道防線:上線前 AI code review 流程
功能都做完、準備 push 上線前,走一次完整 review。流程六步:

關鍵是第 1 步:先 /clear 開新對話。剛陪你寫完程式的那個對話,對自己的產出有「護短」傾向——它記得每段程式碼「為什麼這樣寫」,容易幫自己找理由。乾淨的新對話沒有包袱,更像請了一位外部審查員。然後丟這段總 review prompt:
你是一位資深資安工程師,正在審查一個即將上線的網站專案。
請對整個專案做上線前安全審查,依序檢查:
1. 機密管理:有無寫死的 key/密碼;.env 是否被 git 忽略
2. 輸入驗證:所有 API 是否在後端驗證每個欄位
3. 權限控制:每個 API 是否驗證身分與資料所有權
4. 前端曝險:機密是否可能被打包進瀏覽器端程式碼
5. 其他:錯誤訊息是否洩漏內部細節、有無明顯的注入風險
以表格輸出:風險等級(高/中/低)|檔案:行號|問題|攻擊情境|修法。
高風險 = 上線前必修。不確定的項目標「需人工確認」,不要略過。
拿到分級表之後:高風險一次修一項、修完 git diff 檢查、功能測一下還活著;全部修完把同一段 prompt 再跑一次複掃,確認高風險清零、也沒修出新的洞。中風險排進一週內,低風險記進待辦即可——不用追求一次全綠,追求的是「高風險為零才上線」。
免費工具:讓機器當最後一道網
AI 抓邏輯洞,機器工具抓格式洞,兩層疊著用:

GitHub secret scanning:公開 repo 免費自動開啟,push 上去後掃全 repo(含歷史),比對數百種 key 格式,中獎會寄警報信給你。Push protection 更前面一步:push 的當下就攔截,含已知 key 格式的 commit 根本上不去。到 repo 的 Settings → Code security 確認兩者都是開啟狀態(私有 repo 則要組織的付費方案才有,個人專案用公開 repo 就好)。gitleaks 是開源 CLI,補上「push 之前」這一段:
brew install gitleaks
gitleaks git .
第二行會掃你的工作目錄加整個 git 歷史,幾秒鐘跑完。輸出 no leaks found 就過關;有中的話會列出檔案、行號跟被抓到的字串片段。
Key 真的洩漏了怎麼辦:輪替 SOP
先講鐵律:key 只要進過 git 歷史、或出現在前端程式碼,就當作已經洩漏。把檔案刪掉再 commit 一次沒有用——歷史裡還在,而且掃 GitHub 的機器人是以「分鐘」為單位在撈新洩漏的 key。這時候唯一正確的動作是輪替(rotation):讓舊 key 作廢、換一把新的。

順序不能錯:1. 先撤銷——到發 key 的後台(OpenAI Platform、Anthropic Console、Resend⋯⋯)把外洩的 key Revoke,這步做完壞人手上的就是廢紙;2. 產新 key,只貼進 .env,順手設用量上限;3. 更新兩個地方——本機 .env 和 Vercel 環境變數都換新值,然後 Redeploy,不然正式站還拿著已作廢的舊 key,網站會直接掛;4. 驗傷——回後台看 Usage/Billing 有沒有異常呼叫,有盜用就聯絡客服爭取退費。不需要去清 git 歷史,那又難又容易出錯;直接讓 key 作廢,10 分鐘結案。
常見坑
坑 1:.env 早就被 commit 過了。 症狀通常是 push 時被 GitHub 攔下,出現類似這樣的錯誤:
remote: error: GH013: Repository rule violations found
remote: - Push cannot contain secrets
remote: —— OpenAI API Key ————————————
remote: locations:
remote: - commit: a1b2c3d path: .env:1
這其實是 push protection 在救你。處理三步:git rm --cached .env(把它移出 git 追蹤,但保留本機檔案)→ 確認 .gitignore 有擋 → commit 後重新 push。然後務必輪替裡面所有的 key——它進過歷史,就算這次 push 被擋下,也照鐵律當作洩漏處理。
坑 2:本機好好的,部署上去就掛。 打開正式站看到 500,Vercel 的 log 出現:
Error: Missing credentials. Please pass an apiKey,
or set the OPENAI_API_KEY environment variable.
原因:.env 只活在你電腦上,Vercel 那邊根本沒有這些變數。到 Settings → Environment Variables 補上,補完要 Redeploy 才生效——十個人有九個卡在忘記重新部署這步。
坑 3:key 用了 NEXT_PUBLIC_ 前綴。 AI 有時會「好心」把環境變數取名 NEXT_PUBLIC_OPENAI_API_KEY,因為這樣前端就讀得到、程式碼最快能動。但 Next.js 裡這個前綴的意思就是「打包進瀏覽器端」,等於 key 直接公開,F12 就搜得到。檢查法:全案搜尋 NEXT_PUBLIC_,凡是 key、token 類的一律去掉前綴,改成只在 API route 用 process.env.X 讀,前端改打自己的 /api/...。改完一樣要輪替那把 key。
坑 4:掃描 prompt 回你「整體看起來安全」這種話。 這是問法太鬆的訊號:沒指定範圍、沒要求輸出格式,AI 就傾向給禮貌性總評。回到模板的三要素——範圍、表格、「沒發現要明講」——重新丟一次;專案大就分資料夾掃。掃描類任務永遠要讓 AI 交「清單」,不是交「感想」。
作業
- 把本課的資安班規段落加進你專案的 CLAUDE.md(照自己專案的技術調整用詞)。
- 對你的網站依序跑三大掃描 prompt,把掃出的高風險全部修掉,並複掃確認清零。
- 跑
git check-ignore -v .env和git ls-files | grep env兩個驗證指令,截圖留存;裝 gitleaks 掃一次 git 歷史。 - 到 GitHub repo 的 Settings → Code security,確認 secret scanning 與 push protection 都是開啟狀態。
下一課:綜合實戰,完整走一遍
工具會了、部署會了、迭代會了、資安也守住了——最後一課把七堂課全部串起來:從零開始做一個作品集網站加聯絡表單,從開案、CLAUDE.md、開發迭代、資安檢查到部署上線,完整走一遍真實專案的全流程。這會是你第一個「照業界節奏」完成的作品,下堂課見。