安全審計技能
對 Web 應用程式程式碼庫執行嚴謹的靜態安全性審計。產出一個摘要表格(通過 / 失敗 / 需人工審查)以及每個發現的詳細區塊,附帶檔案:行號證據、風險描述與修復程式碼。
第一階段——堆疊分類
在掃描任何程式碼之前,先透過閱讀 package.json、設定檔和 README 回答以下問題:
- 框架:SvelteKit / Next.js / Express / FastAPI 等
- 資料庫驅動:參數化(libsql, pg, prisma) vs. 原始字串(較低層級的驅動)
- 驗證機制:JWT / HMAC 令牌 / Session / OAuth
- 部署目標:Fly.io / Cloudflare / Vercel / 原生 Node——這決定了速率限制與稽核日誌應信任哪個 IP 標頭(
Fly-Client-IPvsCF-Connecting-IPvsX-Forwarded-For);信任錯誤的標頭會讓攻擊者偽造其來源 IP - 檔案上傳:是/否——如果是,儲存在何處(本地檔案系統、S3 相容、CDN)
- 外部傳出請求:電子郵件 API、Webhook、媒體擷取——潛在的 SSRF 攻擊面
在第二階段之前,用一個段落說明你的堆疊摘要。這裡的錯誤假設會導致錯誤的發現。
第二階段——掃描
必須閱讀:references/security-checklist.md
針對單一端點審查時,不要載入 references/security-checklist.md——這會將範圍擴大到超出任務之外。僅在完整程式碼庫審計時才載入它。
按順序處理檢查清單中的每一個類別——跳過任何類別需要在報告中寫明理由。
針對每個類別:
- 閱讀相關的原始檔。不要憑記憶標記「通過」。
- 如果檔案不存在,則標記為「需人工審查」並附上備註。
- 記錄判定結果(通過 / 失敗 / 需人工審查)與一行證據備註。
如果儲存庫太大而無法讀取所有檔案,請按風險排序:優先處理驗證流程和金鑰處理,然後是輸入/輸出邊界,最後是依賴設定。備註哪些檔案被跳過。
第三階段——分類
檢閱你的原始掃描備註。針對每個項目,套用判定規則:
- 通過——你已閱讀相關程式碼並確認該控制措施已就位。引用檔案:行號。
- 失敗——你找到一個確認可被利用的漏洞。你有一段程式碼片段。你能寫出修復程式碼。
- 需人工審查——該判定需要執行時期上下文、基礎設施存取權限或人為判斷(例如「驗證此令牌在 Turso 儀表板上是否具有唯讀範圍」)。
在指定判定之前,先問:「我現在能否僅根據我所讀到的內容,寫出修復程式碼?」是→失敗。否→需人工審查。
不要為了軟化報告而將「失敗」降級為「需人工審查」。
第四階段——報告
先放摘要表格:
| # | 類別 | 狀態 | 備註 |
|---|---|---|---|
| 1 | SQL 注入 | 通過 | 全程使用參數化查詢 |
| 2 | XSS | 失敗 | {@html} 用於使用者控制的欄位——參見發現 |
| … | … | … | … |
然後,針對每個「失敗」與「需人工審查」,放一個發現區塊:
### [N]. 類別——失敗
**檔案:** `src/lib/example.ts:42`
**程式碼片段:**
cookies.set(name, token, { httpOnly: true }) // ← 缺少 Secure 標記
**風險:** Cookie 在非正式環境中透過純文字 HTTP 傳輸;可能被被動中間人攻擊擷取。
**修復:**
cookies.set(name, token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
});
「需人工審查」區塊使用相同格式,但將修復替換為行動,說明人員必須驗證什麼以及在哪裡驗證。
「通過」項目僅出現在摘要表格中——不需要區塊。
絕不
-
絕不未經讀取檔案就標記「通過」 替代做法: 讀取檔案,在證據備註中引用檔案:行號。 原因: 基於記憶的「通過」判定會產生虛假保證——審計的意義就在於證據。
-
絕不標記「失敗」卻沒有程式碼片段 替代做法: 引用確切的薄弱行。如果你找不到片段,就是「需人工審查」。 原因: 沒有證據的「失敗」只是噪音;開發者需要確切位置才能修復。
-
絕不混淆「失敗」與「需人工審查」 替代做法:「失敗」= 你現在可以寫出修復程式碼。「需人工審查」= 你不能,並說明原因。 原因: 混用兩者會破壞報告的可執行性。
-
絕不跳過第一階段的堆疊分類 替代做法: 在掃描任何東西之前先讀取
package.json和一個設定檔。 原因: 要信任哪個 IP 標頭、哪種 CSP 方法有效、以及哪種驗證模型適用,都取決於堆疊——錯誤的假設會連鎖導致錯誤的判定。 -
絕不報告不符合專案框架/函式庫的修復程式碼 替代做法: 使用專案中已使用的確切 API 來撰寫修復(例如 SvelteKit 的
cookies.set,而非res.setHeader)。 原因: 無法編譯的通用修復會被忽略;針對特定框架的修復才會被合併。 -
絕不為尚未讀取原始檔的類別撰寫發現區塊 替代做法: 開啟檔案、讀取它,然後再寫區塊。 原因: 沒有檔案證據的發現區塊只是斷言,不是審計——一旦被發現是錯誤的,就會削弱對整個報告的信任。
-
絕不默默地跳過大型儲存庫中的檔案 替代做法: 按風險排序(驗證/金鑰處理 → 輸入/輸出邊界 → 依賴設定),並在報告中明確列出每個被跳過的檔案。 原因: 默默跳過會使審計的覆蓋範圍宣稱無法驗證——不完整的掃描卻呈現出乾淨的報告,讀起來就像是虛假的「一切安全」信號。