用 Claude Code 做 Code Review:比人工更快更全面


這篇文章延續並擴大了之前的安全性審查: 📖 AI Code Review:用 Claude Code 檢查 Legacy 程式碼的安全性


🎯 前言

人工 Code Review 有兩個天生的弱點:

  1. 不一致:同一個人星期一和星期五的審查標準不同
  2. 有盲點:你熟悉的問題看得到,不熟悉的問題看不到

Claude Code 不會累、不會分心,而且可以同時從安全性、效能、可維護性三個角度審查。它不能取代人工 review(業務邏輯的判斷仍然需要人),但它能覆蓋人容易漏掉的地方

這篇文章分享我用 Claude Code 做 Code Review 的完整方法。


📂 三個審查面向

我把 Code Review 拆成三個獨立的面向,每次可以只跑一個或全部跑:

面向關注什麼適合什麼時候
安全性SQL injection、XSS、敏感資料洩漏每次 PR 都跑
效能N+1 查詢、不必要的迴圈、缺少索引涉及資料庫或大量資料時
可維護性重複程式碼、過度複雜、命名不清重構或新功能時

🔍 安全性審查

基本用法

你:review src/api/ 目錄中所有 API endpoint 的安全性,
    專注在 SQL injection、XSS、認證繞過。
    用表格列出發現的問題。

Claude 會逐一讀取檔案,輸出類似這樣的結果:

| 檔案 | 行號 | 問題類型 | 嚴重度 | 說明 |
|------|------|---------|--------|------|
| api/users.php | 34 | SQL Injection | 高 | 直接拼接 $_GET 到查詢 |
| api/export.php | 12 | Path Traversal | 高 | 未驗證檔案路徑 |
| api/profile.php | 78 | XSS | 中 | 輸出未經 htmlspecialchars |

進階:指定檢查清單

給 Claude 一份具體的檢查清單,結果更全面:

你:用以下清單審查 src/api/:

安全性檢查清單:
1. SQL 查詢是否使用參數化(prepared statement)
2. 使用者輸入是否有驗證和過濾
3. 輸出是否有適當的 encoding(HTML、JSON)
4. 檔案操作是否有路徑驗證
5. 認證/授權檢查是否在每個 endpoint 都有
6. 敏感資料(密碼、token)是否有在 log 中被記錄
7. CSRF 防護是否到位
8. 錯誤訊息是否洩漏內部資訊

Legacy PHP 特有的安全問題

如果你的專案是 Legacy PHP(像我的 AppSystem),可以加上這些專項:

你:另外特別檢查這些 Legacy PHP 常見問題:
1. 有沒有用 mysql_* 函數(應該用 PDO)
2. $_REQUEST 的使用(應該用 $_GET 或 $_POST)
3. register_globals 遺留的寫法
4. extract() 的使用
5. eval() 或 preg_replace 的 /e 修飾符

⚡ 效能審查

資料庫效能

你:review src/models/ 中的資料庫查詢效能:
1. 找出 N+1 查詢(迴圈中的查詢)
2. 找出 SELECT *(應該指定欄位)
3. 找出缺少 LIMIT 的查詢
4. 找出可能需要索引的 WHERE 條件

輸出範例:

| 檔案 | 行號 | 問題 | 影響 | 建議 |
|------|------|------|------|------|
| models/User.php | 89 | N+1 查詢 | 高 | foreach 中查詢 roles,改用 JOIN |
| models/Report.php | 34 | SELECT * | 中 | 只需要 id 和 name |
| models/Log.php | 56 | 無 LIMIT | 高 | 歷史 log 可能有百萬筆 |

前端效能

你:review src/components/ 的效能:
1. 不必要的重渲染
2. 大型陣列沒有虛擬化
3. 圖片沒有 lazy loading
4. bundle size 可以優化的地方

🔧 可維護性審查

你:review src/lib/ 的可維護性:
1. 超過 200 行的函數
2. 超過 3 層的巢狀 if/else
3. 重複的程式碼片段(copy-paste)
4. 命名不清楚的變數或函數
5. 缺少錯誤處理的地方
6. 寫死的 magic number

這個面向最適合在重構前跑一次,幫你盤點要改的地方。


📋 完整的 Review 流程

方法 1:一次性全面 review

適合 PR 審查或定期程式碼健檢:

你:全面 review src/ 目錄,從安全性、效能、可維護性三個面向。
    每個面向用獨立的表格列出發現。
    嚴重度分三級:高、中、低。
    最後給一個總結和優先處理建議。

方法 2:針對 git diff review

只審查這次 PR 改動的部分:

你:review 這次的改動:
    先跑 git diff main...HEAD 看修改了什麼,
    然後針對改動的部分做安全性和效能審查

這比全面 review 快很多,適合日常 PR 流程。

方法 3:用角色強化特定面向

你:你現在是一個有 10 年經驗的資安專家。
    這段 PHP 程式碼要上線了,做最後一次安全審查。
    假設攻擊者會嘗試所有可能的輸入。

角色設定會改變 Claude 的注意力分配——「資安專家」會更嚴格地檢查安全問題,「效能工程師」會更注意執行效率。


🤖 用 Hooks 自動化 Review

每次 commit 前自動 review

搭配 Claude Code Hooks,在 Claude 完成修改後自動跑安全檢查:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "檢查這次對話中修改的所有檔案,是否有明顯的安全問題(SQL injection、XSS、敏感資料洩漏)。如果有問題回傳 {\"ok\": false, \"reason\": \"問題描述\"},沒問題回傳 {\"ok\": true}。",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

這個 hook 用 prompt 類型——派一個輕量 LLM 做快速判斷。如果發現問題,Claude 會被阻止停止,繼續修正。

編輯後自動檢查特定模式

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash scripts/check_patterns.sh",
            "statusMessage": "檢查危險模式..."
          }
        ]
      }
    ]
  }
}

scripts/check_patterns.sh

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
  exit 0
fi

ISSUES=""

# 檢查 PHP 危險模式
case "$FILE_PATH" in
  *.php)
    if grep -n 'eval(' "$FILE_PATH" 2>/dev/null; then
      ISSUES="${ISSUES}\n⚠️ eval() 使用"
    fi
    if grep -n '\$_REQUEST' "$FILE_PATH" 2>/dev/null; then
      ISSUES="${ISSUES}\n⚠️ \$_REQUEST 使用(建議用 \$_GET 或 \$_POST)"
    fi
    if grep -n 'mysql_query' "$FILE_PATH" 2>/dev/null; then
      ISSUES="${ISSUES}\n⚠️ mysql_* 函數(建議用 PDO)"
    fi
    ;;
esac

# 檢查通用危險模式
if grep -n 'password.*=' "$FILE_PATH" 2>/dev/null | grep -v 'password.*\$' | grep -v '//' ; then
  ISSUES="${ISSUES}\n⚠️ 可能的硬寫密碼"
fi

if [ -n "$ISSUES" ]; then
  echo -e "在 $FILE_PATH 中發現潛在問題:$ISSUES" >&2
  # 用 exit 0 不阻擋,只提醒
fi

exit 0

💡 讓 Review 結果更有用的技巧

技巧 1:要求附帶修復建議

你:review 時,每個問題都附上具體的修復程式碼片段,
    不只是說「這裡有 SQL injection」,
    要給出修正後的程式碼

技巧 2:按嚴重度排序

你:結果按嚴重度排序(高 → 中 → 低),
    先列出最需要立刻修的問題

技巧 3:區分「必須修」和「建議修」

你:把發現分成兩類:
    🔴 必須修(安全漏洞、會影響使用者)
    🟡 建議修(效能、可維護性改善)

技巧 4:批次修復

Review 完之後,直接讓 Claude 修:

你:把剛才列出的所有 🔴 必須修 的問題修掉

Claude 會按照 review 的結果逐一修復。這就是「AI review + AI 修」的完整迴圈。


⚠️ Claude Review 的限制

1. 業務邏輯判斷不了

Claude 能發現:
✅ getUserById 沒有處理 null
✅ 查詢缺少 LIMIT

Claude 判斷不了:
❌ 這個折扣邏輯對不對
❌ 這個表單欄位的驗證規則符不符合業務需求

業務邏輯的對錯仍然需要人來判斷。

2. 跨檔案的複雜流程

Claude 一次能讀的檔案有限。如果一個安全問題涉及 A 檔案的輸入、B 檔案的處理、C 檔案的輸出,Claude 需要你明確指出這三個檔案之間的關聯。

✅ "review 這個資料流:
    1. src/api/upload.php 接收檔案
    2. src/lib/storage.php 存檔
    3. src/pages/download.php 提供下載
    檢查整個流程的安全性"

3. 不能取代真正的安全測試

Claude 做的是靜態分析——看程式碼找問題。它不會真正執行程式碼、不會嘗試攻擊、不會測試 runtime 行為。

Claude review 是額外的防線,不是唯一的防線。


🎉 結語

用 Claude Code 做 Code Review 的最大價值是一致性覆蓋率

人工 review 會因為時間壓力跳過某些檢查,Claude 不會。人工 review 可能不熟悉某些安全攻擊模式,Claude 都知道。

我的建議:

  1. 日常 PR:用 git diff 只 review 改動的部分
  2. 定期健檢:每月一次全面 review
  3. 自動化:用 Hooks 的 prompt 類型做即時安全檢查
  4. 人工把關:業務邏輯的判斷留給人

兩者搭配,覆蓋率最高。


📎 相關文章