Security Audit - 深度安全審計
自動觸發時機
Claude 會在以下情況自動執行此 skill:
| 觸發情境 | 說明 |
|---|---|
| 處理用戶輸入 | 任何接收外部輸入的代碼 |
| 資料庫操作 | 新增或修改 SQL 查詢 |
| API 端點 | 建立或修改 API routes |
| 認證授權 | 涉及登入、權限檢查的代碼 |
| 檔案操作 | 處理檔案上傳/下載 |
| 用戶要求 | 用戶說「安全檢查」、「audit」 |
OWASP Top 10 檢查清單
1. A01 - Broken Access Control(存取控制失效)
markdown
□ API 端點有權限檢查 □ 用戶只能存取自己的資料 □ 敏感操作需要重新驗證 □ CORS 設定正確 □ 目錄遍歷防護
檢查模式:
typescript
// ❌ 危險:沒有權限檢查
router.get("/user/:id", async (c) => {
return db.query.users.findFirst({ where: eq(users.id, id) });
});
// ✅ 安全:有權限檢查
router.get("/user/:id", authMiddleware, async (c) => {
const currentUser = c.get("user");
if (currentUser.id !== id && !currentUser.isAdmin) {
throw new ForbiddenError();
}
return db.query.users.findFirst({ where: eq(users.id, id) });
});
2. A02 - Cryptographic Failures(加密失敗)
markdown
□ 密碼使用安全雜湊(bcrypt/argon2) □ 敏感資料傳輸使用 HTTPS □ JWT secret 足夠強度 □ 不儲存明文密碼 □ 適當的 session 管理
3. A03 - Injection(注入攻擊)
markdown
□ SQL 查詢使用參數化 □ 沒有字串拼接 SQL □ 命令執行有適當轉義 □ 模板引擎有自動轉義
檢查模式:
typescript
// ❌ 危險:SQL Injection
const result = await db.execute(
`SELECT * FROM users WHERE id = '${userId}'`
);
// ✅ 安全:參數化查詢
const result = await db.query.users.findFirst({
where: eq(users.id, userId)
});
4. A04 - Insecure Design(不安全設計)
markdown
□ 業務邏輯有防濫用機制 □ Rate limiting 實作 □ 敏感操作有確認步驟 □ 錯誤訊息不洩漏內部資訊
5. A05 - Security Misconfiguration(安全設定錯誤)
markdown
□ 生產環境關閉 debug 模式 □ 預設帳號密碼已變更 □ 不必要的功能已停用 □ 安全標頭已設定(CSP, X-Frame-Options) □ 錯誤處理不暴露堆疊追蹤
6. A06 - Vulnerable Components(易受攻擊的元件)
markdown
□ 依賴套件定期更新 □ 沒有已知漏洞的套件 □ 使用 lockfile 鎖定版本
檢查命令:
bash
bun audit
7. A07 - Authentication Failures(認證失敗)
markdown
□ 密碼強度要求 □ 登入失敗限制 □ Session 過期機制 □ 安全的「忘記密碼」流程 □ MFA 支援(如適用)
8. A08 - Data Integrity Failures(資料完整性失敗)
markdown
□ 反序列化有驗證 □ CI/CD pipeline 安全 □ 套件來源可信
9. A09 - Logging Failures(日誌記錄失敗)
markdown
□ 登入事件有記錄 □ 敏感操作有稽核日誌 □ 日誌不包含敏感資訊 □ 日誌有適當保留期限
10. A10 - SSRF(伺服器端請求偽造)
markdown
□ 外部 URL 請求有白名單 □ 內部網路位址被阻擋 □ 重導向有驗證
執行流程
步驟 1: 識別審計範圍
根據變更內容決定審計重點:
| 變更類型 | 重點檢查 |
|---|---|
| API 路由 | A01, A03, A07 |
| 資料庫操作 | A03, A01 |
| 認證代碼 | A02, A07 |
| 用戶輸入處理 | A03, A07 |
| 外部 API 調用 | A10 |
步驟 2: 靜態分析
掃描常見的不安全模式:
bash
# 搜尋可能的 SQL injection
grep -r "execute.*\$\{" --include="*.ts"
grep -r "query.*\+" --include="*.ts"
# 搜尋硬編碼憑證
grep -r "password\s*=" --include="*.ts"
# 搜尋不安全的 eval
grep -r "eval\(" --include="*.ts"
步驟 3: 代碼審查
對關鍵區域進行深度審查:
- •
packages/api/src/routers/- API 端點 - •
packages/auth/- 認證邏輯 - •
packages/db/- 資料庫操作 - •
packages/services/- 業務邏輯
步驟 4: 輸出報告
輸出格式
markdown
## 🔒 Security Audit 報告
### 📊 摘要
- **審計範圍**: X 個檔案
- **發現問題**: 🔴 嚴重 X | 🟠 高 X | 🟡 中 X | 🟢 低 X
- **安全評分**: X/100
### 🔴 嚴重問題(必須立即修復)
#### [OWASP-A03] SQL Injection
**檔案**: `packages/api/src/routers/search.ts:45`
**描述**: 使用字串拼接建構 SQL 查詢
**影響**: 攻擊者可執行任意 SQL 命令
**修復建議**:
\`\`\`typescript
// ❌ 當前代碼
const result = await db.execute(\`SELECT * FROM users WHERE name LIKE '%\${search}%'\`);
// ✅ 修復後
const result = await db.query.users.findMany({
where: like(users.name, \`%\${search}%\`)
});
\`\`\`
### 🟠 高風險問題
#### [OWASP-A01] 缺少權限檢查
**檔案**: `packages/api/src/routers/opportunity.ts:120`
**描述**: API 端點沒有驗證用戶是否有權限存取該資源
### 🟡 中風險問題
...
### 🟢 低風險問題
...
### ✅ 安全的實作
- 認證使用 Better-Auth(安全的 session 管理)
- 密碼使用 bcrypt 雜湊
- CORS 設定正確
### 📝 建議改進
1. 實作 Rate Limiting
2. 新增 CSP 標頭
3. 啟用稽核日誌
### ✅ 下一步行動
1. [ ] 修復嚴重問題
2. [ ] 修復高風險問題
3. [ ] 執行測試驗證
4. [ ] 安排定期安全審計
專案特定安全考量
此專案的安全重點
| 元件 | 安全考量 |
|---|---|
packages/auth | Better-Auth 設定、session 管理 |
packages/api | oRPC 輸入驗證、權限檢查 |
packages/db | Drizzle 參數化查詢 |
apps/slack-bot | Slack 簽名驗證 |
packages/services | API Key 管理、外部服務調用 |
已知安全機制
- •認證: Better-Auth with PostgreSQL adapter
- •授權: Role-based (admin, sales, viewer)
- •輸入驗證: Zod schemas in oRPC
- •ORM: Drizzle (防 SQL injection)
整合的工具
| 工具 | 用途 |
|---|---|
Read | 讀取代碼審查 |
Grep | 搜尋不安全模式 |
Glob | 找出關鍵檔案 |
相關 Skills
- •
/secret-scanner- 敏感資訊掃描 - •
/code-review- 一般代碼審查 - •
/test- 安全測試驗證