SKILL.md
唯讀
名稱
secure-code-guardian
描述
在實作身分驗證/授權、保護使用者輸入或預防 OWASP Top 10 弱點時使用——包括自訂安全實作,例如使用 bcrypt/argon2 雜湊密碼、使用參數化陳述式清理 SQL 查詢、設定 CORS/CSP 標頭、使用 Zod 驗證輸入,以及設定 JWT Token。適用於身分驗證、授權、輸入驗證、加密、OWASP Top 10 預防、安全 Session 管理及安全強化。若需預先建置的 OAuth/SSO 整合或獨立安全稽核,請考慮使用更專門的技能。
Secure Code Guardian
核心工作流程
- 威脅建模 — 識別攻擊面與威脅
- 設計 — 規劃安全控制措施
- 實作 — 撰寫具縱深防禦的安全程式碼;請參閱下方程式碼範例
- 驗證 — 透過明確的檢查點測試安全控制措施(見下方)
- 文件化 — 記錄安全決策
驗證檢查點
每個實作步驟完成後,請確認:
- 身分驗證:測試暴力破解防護(鎖定/速率限制觸發)、Session 固定攻擊防護、Token 過期機制,以及無效憑證的錯誤訊息(不得洩漏使用者是否存在)。
- 授權:確認水平與垂直權限提升路徑已被阻擋;使用不同角色/使用者的 Token 進行測試。
- 輸入處理:確認 SQL 注入 payload(
' OR 1=1--)被拒絕;確認 XSS payload(<script>alert(1)</script>)被跳脫或拒絕。 - 標頭/CORS:使用安全掃描工具(例如
curl -I、Mozilla Observatory)驗證安全標頭是否存在,且 CORS 來源白名單正確。
參考指南
根據情境載入詳細指引:
| 主題 | 參考文件 | 載入時機 |
|---|---|---|
| OWASP | references/owasp-prevention.md |
OWASP Top 10 模式 |
| 身分驗證 | references/authentication.md |
密碼雜湊、JWT |
| 輸入驗證 | references/input-validation.md |
Zod、SQL 注入 |
| XSS/CSRF | references/xss-csrf.md |
XSS 預防、CSRF |
| 標頭 | references/security-headers.md |
Helmet、速率限制 |
限制
必須執行
- 使用 bcrypt/argon2 雜湊密碼(絕不使用 MD5/SHA-1/未加鹽雜湊)
- 使用參數化查詢(絕不使用字串插值 SQL)
- 在使用前驗證並清理所有使用者輸入
- 在身分驗證端點實作速率限制
- 設定安全標頭(CSP、HSTS、X-Frame-Options)
- 記錄安全事件(身分驗證失敗、權限提升嘗試)
- 將機密儲存在環境變數或機密管理器中(絕不放在原始碼中)
絕對禁止
- 以明文或可逆加密形式儲存密碼
- 未經驗證就信任使用者輸入
- 在日誌或錯誤回應中暴露敏感資料
- 使用弱式或已淘汰的演算法(MD5、SHA-1、DES、ECB 模式)
- 在程式碼中硬編碼機密或憑證
程式碼範例
密碼雜湊(bcrypt)
import bcrypt from 'bcrypt';
const SALT_ROUNDS = 12; // 最低 10;12 在安全性與效能間取得平衡
export async function hashPassword(plaintext: string): Promise<string> {
return bcrypt.hash(plaintext, SALT_ROUNDS);
}
export async function verifyPassword(plaintext: string, hash: string): Promise<boolean> {
return bcrypt.compare(plaintext, hash);
}
參數化 SQL 查詢(Node.js / pg)
// 絕不:`SELECT * FROM users WHERE email = '${email}'`
// 永遠:使用位置參數
import { Pool } from 'pg';
const pool = new Pool();
export async function getUserByEmail(email: string) {
const { rows } = await pool.query(
'SELECT id, email, role FROM users WHERE email = $1',
[email] // 值單獨傳遞——絕不進行字串插值
);
return rows[0] ?? null;
}
使用 Zod 進行輸入驗證
import { z } from 'zod';
const LoginSchema = z.object({
email: z.string().email().max(254),
password: z.string().min(8).max(128),
});
export function validateLoginInput(raw: unknown) {
const result = LoginSchema.safeParse(raw);
if (!result.success) {
// 回傳通用錯誤——絕不回傳原始輸入
throw new Error('Invalid credentials format');
}
return result.data;
}
JWT 驗證
import jwt from 'jsonwebtoken';
const JWT_SECRET = process.env.JWT_SECRET!; // 絕不硬編碼
export function verifyToken(token: string): jwt.JwtPayload {
// 若過期、遭竄改或演算法錯誤則拋出例外
const payload = jwt.verify(token, JWT_SECRET, {
algorithms: ['HS256'], // 明確白名單演算法
issuer: 'your-app',
audience: 'your-app',
});
if (typeof payload === 'string') throw new Error('Invalid token payload');
return payload;
}
保護端點安全——完整流程
import express from 'express';
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';
const app = express();
app.use(helmet()); // 設定 CSP、HSTS、X-Frame-Options 等
app.use(express.json({ limit: '10kb' })); // 限制 payload 大小
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分鐘
max: 10, // 每個 IP 每個時間視窗最多 10 次嘗試
standardHeaders: true,
legacyHeaders: false,
});
app.post('/api/login', authLimiter, async (req, res) => {
// 1. 驗證輸入
const { email, password } = validateLoginInput(req.body);
// 2. 身分驗證——參數化查詢、常數時間比較
const user = await getUserByEmail(email);
if (!user || !(await verifyPassword(password, user.passwordHash))) {
// 通用訊息——不揭露 email 是否存在
return res.status(401).json({ error: 'Invalid credentials' });
}
// 3. 授權——發行範圍限定、短效期的 Token
const token = jwt.sign(
{ sub: user.id, role: user.role },
JWT_SECRET,
{ algorithm: 'HS256', expiresIn: '15m', issuer: 'your-app', audience: 'your-app' }
);
// 4. 安全回應——Token 放在 httpOnly Cookie 中,而非回應主體
res.cookie('token', token, { httpOnly: true, secure: true, sameSite: 'strict' });
return res.json({ message: 'Authenticated' });
});
輸出範本
實作安全功能時,請提供:
- 安全實作程式碼
- 注意到的安全考量
- 設定需求(環境變數、標頭)
- 測試建議
知識參考
OWASP Top 10、bcrypt/argon2、JWT、OAuth 2.0、OIDC、CSP、CORS、速率限制、輸入驗證、輸出編碼、加密(AES、RSA)、TLS、安全標頭




