AI 工具 18 min read

claude-code-security-review 拆解:一份值得抄的 AI 資安審查 prompt

Anthropic 2025-08-04 開的 MIT / Python 專案,做成 GitHub Action 在 PR diff 上跑資安審查,另附一個 /security-review slash command 可在本機 Claude Code 直接用。prompt 設計紮實(>80% 可利用性門檻、三階段方法論、結構化 JSON 輸出),但最後 push 停在 2026-02-11、79 個 open issue,而且那層 AI 誤判過濾因為寫死已退役的模型早就靜默停用了。

claude-code-security-review 拆解:一份值得抄的 AI 資安審查 prompt
本文目錄 · 9

Anthropic 在 2025 年 8 月開源了 claude-code-security-review:一個 GitHub Action,PR 一開就讓 Claude 讀那次的 diff,找出新引入的資安漏洞,然後把 finding 直接留成 PR 的行內評論。同一套分析能力也被包成 Claude Code 內建的 /security-review 斜線指令。

把 repo clone 下來逐檔讀完之後,我認為這個專案最值得看的不是那個 Action,是 claudecode/prompts.py 那 175 行。它把「怎麼叫 LLM 做資安審查而不製造雜訊」寫成了一份可以直接抄走的規格:信心門檻量化成數字、排除清單重複兩次、強制三階段方法論、輸出 schema 逼模型寫出攻擊情境。這些設計換個模型、換個實作都還成立。

所以這篇的重心放在拆那份 prompt。它的維護狀態與已知問題我也會據實寫,放在後面一節,你在決定要不要放進 CI 之前需要知道。

本文所有數字與行為描述都來自 2026 年 8 月 3 日當天的 anthropics/claude-code-security-review 主分支。

claude-code-security-review 是什麼

一句話:一個掛在 pull request 上的 GitHub Action,用 Claude 讀 PR diff 做語意層資安審查,只回報它認為高信心、真的可被利用的漏洞。

repo 基本資料:

項目內容
Repoanthropics/claude-code-security-review
授權MIT
主要語言Python
形態GitHub Action(composite)+ Claude Code /security-review 指令
首次公開2025-08-04
Star / Fork5,736 / 614
總 commit 數30
最後 push2026-02-11
開啟中的 issue79
最後三行是使用前該知道的事實:30 個 commit、最後一次 push 停在 2026 年 2 月、79 個 issue 開著。這個 repo 的維護節奏是發布時衝一波、之後幾乎靜止。細節與影響我留到後面「維護狀態」那節講,先看它的設計。

最小可用設定

README 的 Quick Start 就是全部,貼進 .github/workflows/security.yml

name: Security Review

permissions:
pull-requests: write
contents: read

on:
pull_request:

jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2

- uses: anthropics/claude-code-security-review@main
with:
comment-pr: true
claude-api-key: ${{ secrets.CLAUDE_API_KEY }}

fetch-depth: 2 是必要的——它要拿到 diff 就得有前一個 commit。API key 必須同時開通 Claude API 和 Claude Code 用途,只開一邊會失敗。

action.yml 提供的輸入參數:

參數預設作用
claude-api-key無(必填)API 金鑰
comment-prtrue是否在 PR 留言
upload-resultstrue是否上傳結果為 artifact
exclude-directories逗號分隔的排除目錄
claude-model空 → claude-opus-4-1-20250805分析用的模型
claudecode-timeout20分析逾時(分鐘)
run-every-commitfalse每個 commit 都跑(跳過快取)
false-positive-filtering-instructions自訂假陽性過濾規則檔路徑
custom-security-scan-instructions自訂掃描規則檔路徑
claudecode/constants.py 裡的預設值是 claude-opus-4-1-20250805,那是 2025 年 8 月的模型。你現在要用,claude-model 這個參數應該自己填,不要吃預設。

它的 prompt 設計:整個專案最值得抄的部分

一句話:這不是「幫我找漏洞」的一句話 prompt,是一份把「什麼該報、什麼不該報」量化成規則的審查規格。

175 行裡有四個設計值得單獨拆開講。

一、信心門檻量化成數字,不講「請謹慎判斷」

大部分人寫審查 prompt 會寫「請避免誤判」——這種話對模型幾乎沒有約束力,因為它無法對照。這份 prompt 的做法是給出可對照的刻度:Only flag issues where you're >80% confident of actual exploitability,然後要求每個 finding 自己附一個 confidence 數值,並把每個區間該對應什麼證據強度寫清楚:

- 0.9-1.0: Certain exploit path identified, tested if possible
  • 0.8-0.9: Clear vulnerability pattern with known exploitation methods
  • 0.7-0.8: Suspicious pattern requiring specific conditions to exploit
  • Below 0.7: Don't report (too speculative)
「>80%」跟「0.7 以下不要報」是兩個不同的閘門,一個管要不要開口、一個管開口之後怎麼標。合起來的效果是:模型沒辦法用一句「可能有風險」蒙混過去,它得先把自己放到刻度上。

二、排除清單寫兩次,位置刻意分開

prompt 在開頭和結尾各寫一次「不要報什麼」——這個重複是刻意的,不是贅字。長 prompt 的中段最容易被稀釋,把約束放在頭尾兩端才守得住。

排除的項目:DOS 與資源耗盡、磁碟上的機密(另有流程處理)、rate limiting、記憶體與 CPU 耗盡、以及「沒有證明出實際問題的輸入驗證缺失」。最後一條原文很直白:

If there isn't a proven problem from a lack of input validation, don't report it.

這句話擋掉的是資安審查最大宗的雜訊來源。「這裡沒做輸入驗證」永遠成立、永遠可以報,但多數時候不構成漏洞——把它排除掉,報告才不會被淹沒。

三、三階段方法論:先讀懂專案的安全慣例,再看這次改動

這是我認為最值得抄的一段。它不是叫模型直接看 diff,而是規定順序:

階段做什麼
Phase 1用檔案搜尋工具讀懂 repo 既有的資安框架、既有的驗證與消毒慣例、專案的威脅模型
Phase 2拿新程式碼跟既有慣例比對,找出偏離處與不一致的實作
Phase 3才逐檔評估,追資料流、找越權邊界與注入點
差別在哪:直接看 diff 的模型只會套通用漏洞樣板,於是把專案早就用框架處理掉的東西又報一遍。先建立基準線再比對,找到的才是「這次改動偏離了這個專案原本的安全做法」——那才是 PR 審查真正該抓的東西。

搭配的還有一條範圍限制:focus ONLY on security implications newly added by this PR. Do not comment on existing security concerns. 在 PR 上報一堆既有老問題,結果就是整個 bot 被關掉。

四、輸出 schema 逼出攻擊情境

結尾一句 Your final reply must contain the JSON and nothing else.,配上規定死的欄位:filelineseveritycategorydescriptionexploit_scenariorecommendationconfidence

exploit_scenario 是這個 schema 的關鍵。它逼模型寫出「攻擊者具體怎麼做」——範例給的是 Attacker could extract database contents by manipulating the 'search' parameter with SQL injection payloads like '1; DROP TABLE users--'

這個欄位等於一道自動篩選:寫不出具體利用路徑的 finding,通常本來就不是真漏洞。與其在 prompt 裡再多叮嚀一次「請只報真的漏洞」,不如在輸出格式上要求一個寫不出來就露餡的欄位。

這四個設計加起來就是一句話:把「克制」變成可檢查的結構,而不是形容詞。 這份 prompt 就算你不用這個 Action,也值得拿去改成自己的審查指令——它是這個 repo 最能被複用的部分。

第二層:規則式的硬排除

Claude 回報完之後,claudecode/findings_filter.py 還會再過一次。裡面有一個 HardExclusionRules 類別,用預先編譯的 regex 家族做確定性過濾:

規則家族排除什麼
_DOS_PATTERNS阻斷服務
_RATE_LIMITING_PATTERNS流量限制相關
_RESOURCE_PATTERNS資源耗盡
_OPEN_REDIRECT_PATTERNS開放重導
_MEMORY_SAFETY_PATTERNS記憶體安全(僅在非 C/C++ 檔時排除)
_REGEX_INJECTIONregex 注入
_SSRF_PATTERNSSSRF(僅在 .html 檔時排除)
兩個條件式排除的設計挺細:記憶體安全問題只有在副檔名不是 .c/.cc/.cpp/.h 時才丟掉——在 C/C++ 專案裡記憶體安全是真議題,不能一律過濾。SSRF 只在 .html 檔裡排除,因為純前端模板報 SSRF 基本上是誤判。另外所有 .md 檔的 finding 一律排除。

這是雙層設計:prompt 層要求模型自我克制,規則層再做一次確定性兜底。想法是對的。

第三層:AI 假陽性過濾

過完硬規則之後,還有一層要 Claude 逐條判斷 finding 是不是誤判,並附上判斷理由。README 把 "False Positive Filtering" 列為主打功能之一。

這層的一個細節值得記:單一 finding 的 API 呼叫失敗時,程式碼選擇 fail-open——保留這個 finding,給 confidence_score: 10.0,justification 寫 'Claude API failed: ...'。過濾器壞掉時寧可多報也不要漏報,這個方向是對的。

不過這層現在跑不起來,原因在下一節。

使用前要知道的維護狀態

一句話:這個 repo 目前低維護,而且第三層過濾實際上是關著的。

claudecode/claude_api_client.py 第 62 行的前置檢查把模型寫死成 claude-3-5-haiku-20241022,該模型已退役,呼叫會拿到 404。這個名稱跟你在 claude-model 參數填什麼無關,改不到。失敗被 claudecode/findings_filter.py 第 186 到 195 行接住,use_claude_filtering 設成 False,整個 AI 過濾階段跳過——Action 不會失敗、不回非零 exit code、PR 上看起來一切正常。README 描述三層過濾,實際跑起來是兩層。

這不是我一個人的推論,issue 區有四張直接影響可信度的:

Issue開啟日內容
#1142026-06-20假陽性過濾呼叫已退役模型(404),過濾器靜默降級
#1232026-07-30同一問題,指出此狀態自 2026-02-19 起持續
#1202026-07-20快取 restore-keys 前綴比對導致新 commit 被跳過(假綠燈);可用 run-every-commit: true 繞開
#1182026-07-13action.yml 串接的 actions 仍 pin 在已棄用的 node20
加上最後一次 push 停在 2026-02-11,結論很直接:要放進 CI 就要有自己 fork 維護的準備。 第 62 行那個模型名改掉就能救回第三層,不難,但得你自己改。

README 自己寫明的限制

有一段 README 寫得很誠實,該引:

This action is not hardened against prompt injection attacks and should only be used to review trusted PRs.

它沒有針對 prompt injection 做防護,只該用來審查可信的 PR。官方建議去 repo 設定開啟「Require approval for all external contributors」,讓 workflow 只在維護者審過之後才跑。

這個限制在開源專案上特別要緊:任何人都能開 PR,PR 的內容會進到 prompt 裡。一個惡意的 PR 可以在程式碼註解裡塞指令,試圖讓審查器忽略某段程式碼或輸出誤導性的結論。這不是理論——這是把 LLM 接上不可信輸入的必然風險,而這個 Action 明說自己沒防。

/security-review 指令:不用架 CI 也能用

如果你只是想試試它的分析能力,不必設 GitHub Action。Claude Code 內建 /security-review 斜線指令,用的是同一套分析邏輯,直接審查你目前所有未提交的變更。

想客製化的話,README 給的做法是:把 repo 裡的 .claude/commands/security-review.md 複製到你專案的 .claude/commands/ 底下,然後改。你可以在裡面加上組織專屬的假陽性過濾規則、或補上你們特有的威脅類別。

以「花五分鐘試試值不值得」而言,這條路徑的成本遠低於架 workflow。而且——考慮到前面說的 AI 過濾層問題只發生在 Action 的 Python 管線裡——走指令這條路反而避開了那個坑。

它適合誰、不適合誰

適合: 已經在用 Claude Code、想在 PR 階段多一道語意層檢查的團隊。它的 diff-aware 設計讓成本可控,prompt 的克制程度讓它不會在 PR 上洗版,MIT 授權讓你可以隨意 fork 來改。

不適合以下情況:

你要把它當唯一的資安關卡。 三層過濾現在只有兩層在跑,加上快取那個 bug,它的「綠燈」不能當成保證。規則式 SAST 該留著。

你的 repo 接受外部 PR 且沒開審批。 README 明講沒防 prompt injection。

你需要一個積極維護的相依。 最後 push 停在 2026-02-11、79 個 issue 開著、影響核心功能的 #114 從 6 月掛到現在。要用就要有「自己 fork 來維護」的心理準備。

你不想吃預設模型。 constants.py 的預設是 claude-opus-4-1-20250805,那是 2025 年 8 月的模型。claude-model 這個參數自己填。

我的判斷

一句話:這個專案真正的資產是 prompts.py 那 175 行,Action 只是它的一種封裝。

那份 prompt 解決的是所有人用 LLM 做審查都會遇到的同一個問題——怎麼讓它別把「有可能有風險」都報出來。它的答案不是多寫幾句「請謹慎」,而是四個可檢查的結構:信心門檻量化成刻度、排除清單放在頭尾各一次、規定先讀懂專案慣例再看 diff、輸出 schema 逼出攻擊情境。這四招換到 code review、文件審查、任何要 LLM 做判斷又不能製造雜訊的場景都能用。

Python 管線那邊則示範了另一件事:寫死的模型名稱是 AI 工具最容易踩的地雷。 一行 preflight 的硬編碼,讓整個被當成賣點的過濾階段消失,而流水線照樣報綠。這跟技術難度無關,就是相依沒有跟著模型生命週期走。

實務上怎麼用:想試它的分析能力,直接開 Claude Code 跑 /security-review,成本低,而且避開了 Python 管線那個坑。要放進 CI 就先 fork,把 claude_api_client.py 第 62 行改掉,順便決定快取策略要不要繞開 #120。

不管走哪條路,它都是多一雙眼睛,不是一道門。規則式 SAST 該留著。

# 最低成本的試法:不用架 CI
claude
> /security-review
author
陳彥彤

AI 工程師 · AI 顧問。Java 後端 8 年、AI 工程師 2 年。AI 內訓 · AI 導入顧問 · 前後端與雲端培訓。

support

覺得文章有用可以到 GitHub 給個 star,或是透過信箱聊聊 AI 內訓、AI 導入顧問或前後端 / 雲端培訓。

related

相關文章

[AI 工具] · 17min
OpenAI 官方外掛讓 Codex 進 Claude Code:實測兩種 review,一種漏掉兩個高風險問題
OpenAI 在自己的 GitHub organization 下開源了給 Claude Code 用的官方外掛 codex-plugin-cc(Apache-2.0,撰文當下 30,993 顆星),裝上去就能在 Claude Code 裡直接叫 Codex 審 code 或把任務丟給它跑。我裝了 v1.0.6 並拿一段故意寫壞的批次退款程式碼實測:/codex:review 花 41 秒抓出 2 個 P1;同一份程式碼換 /codex:adversarial-review 抓出 4 個,多的兩個是「刪訂單摧毀稽核軌跡」與「完全沒有退款授權邊界」,標準 review 完全沒提。這篇把安裝步驟、7 個指令的實際差別,以及那個預設關閉、逾時或失敗都會 block 你 session 的 review gate 寫透。
[AI 工具] · 18min
Claude Code agent view 怎麼用?一個看板管住所有背景 agent
claude agents(官方叫 agent view)是 Claude Code 新的背景 agent 控制台:把原本開一堆終端分頁、靠腦子記「哪個 agent 在跑什麼」的混亂,收進一個看板畫面。實測 2.1.212 拆解:看板三分組(等你輸入/執行中/完成)實際怎麼運作、一次派三個 agent 的完整並行工作流、自動 worktree 隔離 + 自動開 draft PR、跟 tmux / subagent 差在哪,以及三個一定要知道的限制。附 Anthropic 官方介紹影片。
[AI 工具] · 14min
Claude Fable 5 升級指南:1M context、$10/$50 定價與 5% 安全閘門全解
Claude Fable 5 是 Anthropic 在 2026-06-09 公開放出的最強模型(model ID claude-fable-5),預設 1M token context、最高 128k 輸出,定價 $10/$50 per M token 剛好是 Opus 4.8 的兩倍。它跟限定釋出的 Mythos 5 是同一顆底層模型,差別只在安全層——Fable 5 內建 safety classifier,平均 <5% 的 session 會在 cybersecurity/biology 等高風險領域被攔下、改由 Opus 4.8 回答(refusal 回 HTTP 200、不計費、可帶 fallbacks 參數自動重試)。它是 Covered Model,30 天資料保留、不支援 ZDR。這篇拆解規格與定價、安全閘門 fallback 機制、在 Claude Code 用 /model claude-fable-5 怎麼切(只有 adaptive thinking、用 effort 控深度),最後給三種人三種升級決策——長 horizon agentic 工作該升、日常任務 Opus 4.8 才是甜蜜點、有 ZDR 需求別升。