精華筆記

· @aihub.tw

Vibe Coding 建站實戰

用 Prompt 守住資安:檢查清單與 AI Code Review

用 Prompt 守住資安:檢查清單與 AI Code Review

上一課看完那些帳單爆炸、資料庫被整包下載的案例,你大概有點睡不著:我的網站也是 AI 寫的,那些洞我有沒有?但打開程式碼一看,滿螢幕看不懂的東西——不會讀程式碼的人,到底要怎麼檢查?

答案其實很直白:讓 AI 檢查 AI。會挖出這些洞的知識,AI 本來就有,它只是在你沒要求的時候不會主動幫你想。差別在問法:丟一句「幫我檢查安全性」,你會得到一頁四平八穩的空話;換成這堂課給你的具體 prompt——指定掃什麼、去哪掃、輸出什麼格式——它就會變成一個相當稱職的資安審查員。這堂課全是可以直接複製的模板,抄走就能用。

這堂課適合誰 適合:用 AI 做了網站、上完第 6 課知道有哪些坑、想動手把洞補起來的人。需要基礎:零程式基礎 OK,但要會用電腦與終端機(第 3 課教過)。前置課:第 5 課(CLAUDE.md)、第 6 課(資安觀念)。本課程屬進階應用專區。

這堂學什麼

  • 三道防線的觀念:生成時防、開發中掃、上線前守門,而不是上線前才臨時抱佛腳
  • CLAUDE.md 資安班規:一段可複製的規則,讓 AI 從源頭就不寫出洞
  • 三大掃描 prompt 模板:掃 secrets、掃輸入驗證、掃權限,附完整可複製版本
  • .env 與 .gitignore 實戰:設定加驗證,確認機密真的沒進 git
  • 上線前 AI code review 六步流程 + key 洩漏的輪替急救 SOP
  • 免費工具:GitHub secret scanning、push protection、gitleaks 怎麼疊著用

觀念:資安是三道防線,不是一次檢查

先建立一個心智模型。很多人以為資安檢查是「上線前跑一次掃描」,但那是最貴的做法:洞已經寫出來、可能已經跟其他程式碼糾纏在一起,拆的成本最高。正確的打法是三道防線:

三道防線:生成時用 CLAUDE.md 防、開發中用掃描 prompt 抓、上線前用 AI review 加工具守門

第一道在生成時:把資安規則寫進 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 特有的地雷(下面會講)。

為什麼這招有效 AI 不是不會寫安全的程式,是在你沒要求時會選「最短能動」的寫法。班規等於把要求變成預設值。從此你不用每次都想到資安,它自己會想到——這是所有防線裡 CP 值最高的一道。

第二道防線:三大掃描 prompt 模板

班規防新程式碼,但已經寫出來的舊程式碼呢?用掃描 prompt。三段模板分別對付第 6 課的三類洞:

三大掃描 prompt 對照:掃 secrets 抓寫死的 key、掃輸入驗證抓信了前端的 API、掃權限抓沒驗身分的入口

模板一:掃 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 類問題的地基就是這兩個檔案,值得專門走一遍。先看懂角色分工:

.env 家族:.env 裝真 key 被 .gitignore 擋住、.env.example 只有欄位名可進 git、正式站的 key 填在 Vercel 後台

確認 .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。流程六步:

上線前 AI code review 六步:開新對話、全面掃描分級、只修高風險、複掃、gitleaks 本機掃、push 讓 GitHub 把關

關鍵是第 1 步:先 /clear 開新對話。剛陪你寫完程式的那個對話,對自己的產出有「護短」傾向——它記得每段程式碼「為什麼這樣寫」,容易幫自己找理由。乾淨的新對話沒有包袱,更像請了一位外部審查員。然後丟這段總 review prompt:

你是一位資深資安工程師,正在審查一個即將上線的網站專案。
請對整個專案做上線前安全審查,依序檢查:
1. 機密管理:有無寫死的 key/密碼;.env 是否被 git 忽略
2. 輸入驗證:所有 API 是否在後端驗證每個欄位
3. 權限控制:每個 API 是否驗證身分與資料所有權
4. 前端曝險:機密是否可能被打包進瀏覽器端程式碼
5. 其他:錯誤訊息是否洩漏內部細節、有無明顯的注入風險
以表格輸出:風險等級(高/中/低)|檔案:行號|問題|攻擊情境|修法。
高風險 = 上線前必修。不確定的項目標「需人工確認」,不要略過。

拿到分級表之後:高風險一次修一項、修完 git diff 檢查、功能測一下還活著;全部修完把同一段 prompt 再跑一次複掃,確認高風險清零、也沒修出新的洞。中風險排進一週內,低風險記進待辦即可——不用追求一次全綠,追求的是「高風險為零才上線」。

AI 說「沒問題」不等於沒問題 專案一大,AI 可能漏看檔案。兩個補強:一是分區掃,「只掃 app/api 底下所有檔案」逐區跑;二是換角度問:「假設你是攻擊者,拿到這個網站的網址,你會從哪裡下手?」攻擊者視角常常挖出防守視角漏掉的東西。所以才需要下面的機器工具當交叉驗證。

免費工具:讓機器當最後一道網

AI 抓邏輯洞,機器工具抓格式洞,兩層疊著用:

免費工具對照:GitHub secret scanning 事後掃、push protection 當下攔、gitleaks 本機主動掃、AI review 抓邏輯洞

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 作廢、換一把新的。

Key 洩漏急救四步:先撤銷舊 key、產新 key、更新 .env 與 Vercel 並 redeploy、回頭查用量帳單

順序不能錯: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 交「清單」,不是交「感想」。

作業

  1. 把本課的資安班規段落加進你專案的 CLAUDE.md(照自己專案的技術調整用詞)。
  2. 對你的網站依序跑三大掃描 prompt,把掃出的高風險全部修掉,並複掃確認清零。
  3. git check-ignore -v .envgit ls-files | grep env 兩個驗證指令,截圖留存;裝 gitleaks 掃一次 git 歷史。
  4. 到 GitHub repo 的 Settings → Code security,確認 secret scanning 與 push protection 都是開啟狀態。

下一課:綜合實戰,完整走一遍

工具會了、部署會了、迭代會了、資安也守住了——最後一課把七堂課全部串起來:從零開始做一個作品集網站加聯絡表單,從開案、CLAUDE.md、開發迭代、資安檢查到部署上線,完整走一遍真實專案的全流程。這會是你第一個「照業界節奏」完成的作品,下堂課見。

#Vibe Coding#資安#AI Code Review#CLAUDE.md#Prompt 模板#GitHub

← 回所有文章