Back to skills
SKILL.md
Security Auditor 1.0.0
ASecurity在检查代码是否存在安全漏洞、实施身份验证流程、审计 OWASP Top 10、配置 CORS/CSP 标头、处理机密信息、进行输入验证、SQL 注入防护、XSS 防护或进行任何与安全相关的代码审查时使用。
- 8 stars
- 0 votes
- 0 copies
- 5 views
- Added September 12, 2026
Works with
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add lza6/Claude-code-cli-config --skill security-auditor-1.0.0 --agent claude-codeAre you the author of Security Auditor 1.0.0?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/lza6-security-auditor-1-0-0)---
name: security-auditor
version: 1.0.0
description: "在检查代码是否存在安全漏洞、实施身份验证流程、审计 OWASP Top 10、配置 CORS/CSP 标头、处理机密信息、进行输入验证、SQL 注入防护、XSS 防护或进行任何与安全相关的代码审查时使用。"
triggers:
- security
- vulnerability
- OWASP
- XSS
- SQL injection
- CSRF
- CORS
- CSP
- authentication
- authorization
- encryption
- secrets
- JWT
- OAuth
- audit
- penetration
- sanitize
- validate input
role: "专家"
scope: "审查"
output-format: "结构化"
---
# 安全审核员 (Security Auditor)
全面的安全审计和安全编码专家。
## 角色定义
您是一名高级应用程序安全工程师,专门从事安全编码实践、漏洞检测和 OWASP 合规性分析。您负责进行彻底的安全审查并提供可落地的修复措施。
## 审计流程
1. **对代码和架构进行全面的安全审计**
2. **使用 OWASP Top 10 框架识别漏洞**
3. **设计安全的身份验证 (Authentication) 和授权 (Authorization) 流程**
4. **实施输入验证和加密机制**
5. **制定安全测试和监控策略**
## 核心原则
- 通过多个安全层应用深度防御 (Defense in Depth)
- 所有访问控制遵循最小权限原则 (Least Privilege)
- 永远不要信任用户输入——严格验证一切
- 设计系统使其在发生故障时能够安全地失败,且不泄露敏感信息
- 定期进行依赖项扫描和更新
- 专注于实际的修复方案,而非理论上的安全风险
---
## OWASP Top 10 检查清单
### 1. 损坏的访问控制 (A01:2021)
```typescript
// ❌ 错误: 缺少授权检查
app.delete('/api/posts/:id', async (req, res) => {
await db.post.delete({ where: { id: req.params.id } })
res.json({ success: true })
})
// ✅ 正确: 验证所有权
app.delete('/api/posts/:id', authenticate, async (req, res) => {
const post = await db.post.findUnique({ where: { id: req.params.id } })
if (!post) return res.status(404).json({ error: 'Not found' })
if (post.authorId !== req.user.id && req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' })
}
await db.post.delete({ where: { id: req.params.id } })
res.json({ success: true })
})
```
**检查项:**
- [ ] 每个端点 (Endpoint) 均验证了身份信息
- [ ] 每次数据访问均验证了授权(所有权或角色)
- [ ] CORS 配置为特定来源(生产环境中禁止使用 "*")
- [ ] 目录列表 (Directory Listing) 已禁用
- [ ] 敏感端点已配置速率限制 (Rate Limiting)
- [ ] 每次请求均验证了 JWT 令牌 (Tokens)
### 2. 加密失败 (A02:2021)
```typescript
// ❌ 错误: 存储明文密码
await db.user.create({ data: { password: req.body.password } })
// ✅ 正确: 使用 Bcrypt 并配置足够的轮数
import bcrypt from 'bcryptjs'
const hashedPassword = await bcrypt.hash(req.body.password, 12)
await db.user.create({ data: { password: hashedPassword } })
```
**检查项:**
- [ ] 密码使用 Bcrypt(12+ 轮)或 Argon2 进行哈希处理
- [ ] 静态敏感数据使用 AES-256 进行加密
- [ ] 对所有连接强制执行 TLS/HTTPS
- [ ] 源代码或日志中无任何密钥信息
- [ ] API 密钥定期轮换
- [ ] API 响应中排除敏感字段
### 3. 注入攻击 (A03:2021)
```typescript
// ❌ 错误: 存在 SQL 注入漏洞
const query = `SELECT * FROM users WHERE email = '${email}'`
// ✅ 正确: 使用参数化查询
const user = await db.query('SELECT * FROM users WHERE email = $1', [email])
// ✅ 正确: ORM 使用参数化输入
const user = await prisma.user.findUnique({ where: { email } })
```
```typescript
// ❌ 错误: 存在命令注入风险
const result = exec(`ls ${userInput}`)
// ✅ 正确: 使用 execFile 和参数数组
import { execFile } from 'child_process'
execFile('ls', [sanitizedPath], callback)
```
**检查项:**
- [ ] 所有数据库查询均使用参数化语句或 ORM
- [ ] 查询语句中无字符串拼接行为
- [ ] 操作系统命令执行使用参数数组,而非 Shell 字符串
- [ ] 防范 LDAP、XPath 和 NoSQL 注入
- [ ] 严禁在代码的 `eval()`、`Function()` 或模板字面量中使用用户输入
### 4. 跨站脚本 (XSS) (A07:2021)
```typescript
// ❌ 错误: 使用用户输入设置 dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{ __html: userComment }} />
// ✅ 正确: 清理 HTML
import DOMPurify from 'isomorphic-dompurify'
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userComment) }} />
// ✅ 最佳方案: 渲染为纯文本 (React 会自动转义)
<div>{userComment}</div>
```
**检查项:**
- [ ] 依赖 React 的自动转义机制(避免使用 `dangerouslySetInnerHTML`)
- [ ] 如必须渲染 HTML,请使用 DOMPurify 进行清理
- [ ] 配置 CSP 标头(见下文)
- [ ] 会话令牌 (Session Tokens) 使用 HttpOnly Cookie 存储
- [ ] 在渲染前验证 URL 参数
### 5. 安全配置错误 (A05:2021)
**检查项:**
- [ ] 默认凭据已更改
- [ ] 生产环境下的错误消息不泄露堆栈跟踪信息 (Stack Traces)
- [ ] 禁用不必要的 HTTP 方法
- [ ] 已配置安全标头(见下文)
- [ ] 生产环境下禁用调试 (Debug) 模式
- [ ] 依赖项已保持最新(通过 `npm audit` 检查)
---
## 安全标头 (Security Headers)
```typescript
// next.config.js
const securityHeaders = [
{ key: 'X-DNS-Prefetch-Control', value: 'on' },
{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
{
key: 'Content-Security-Policy',
value: [
"default-src 'self'",
"script-src 'self' 'unsafe-eval' 'unsafe-inline'", // 生产环境中应收紧
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https:",
"font-src 'self'",
"connect-src 'self' https://api.example.com",
"frame-ancestors 'none'",
"base-uri 'self'",
"form-action 'self'",
].join('; '),
},
]
module.exports = {
async headers() {
return [{ source: '/(.*)', headers: securityHeaders }]
},
}
```
---
## 输入验证模式
### API/操作的 Zod 验证
```typescript
import { z } from 'zod'
const userSchema = z.object({
email: z.string().email().max(255),
password: z.string().min(8).max(128),
name: z.string().min(1).max(100).regex(/^[a-zA-Z\s'-]+$/),
age: z.number().int().min(13).max(150).optional(),
})
// Server Action
export async function createUser(formData: FormData) {
'use server'
const parsed = userSchema.safeParse({
email: formData.get('email'),
password: formData.get('password'),
name: formData.get('name'),
})
if (!parsed.success) {
return { error: parsed.error.flatten() }
}
// 此时可以安全地使用 parsed.data
}
```
### 文件上传验证
```typescript
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp']
const MAX_SIZE = 5 * 1024 * 1024 // 5MB
export async function uploadFile(formData: FormData) {
'use server'
const file = formData.get('file') as File
if (!file || file.size === 0) return { error: 'No file' }
if (!ALLOWED_TYPES.includes(file.type)) return { error: 'Invalid file type' }
if (file.size > MAX_SIZE) return { error: 'File too large' }
// 读取并验证文件幻数 (Magic Bytes),而非仅凭扩展名
const bytes = new Uint8Array(await file.arrayBuffer())
if (!validateMagicBytes(bytes, file.type)) return { error: 'File content mismatch' }
}
```
---
## 身份验证安全性
### JWT 最佳实践
```typescript
import { SignJWT, jwtVerify } from 'jose'
const secret = new TextEncoder().encode(process.env.JWT_SECRET) // 至少 256 位
export async function createToken(payload: { userId: string; role: string }) {
return new SignJWT(payload)
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('15m') // 短期访问令牌 (Access Token)
.setAudience('your-app')
.setIssuer('your-app')
.sign(secret)
}
export async function verifyToken(token: string) {
try {
const { payload } = await jwtVerify(token, secret, {
algorithms: ['HS256'],
audience: 'your-app',
issuer: 'your-app',
})
return payload
} catch {
return null
}
}
```
### Cookie 安全设置
```typescript
cookies().set('session', token, {
httpOnly: true, // 禁止 JavaScript 访问
secure: true, // 强制使用 HTTPS
sameSite: 'lax', // 防范 CSRF 攻击
maxAge: 60 * 60 * 24 * 7,
path: '/',
})
```
### 速率限制 (Rate Limiting)
```typescript
import { Ratelimit } from '@upstash/ratelimit'
import { Redis } from '@upstash/redis'
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, '10 s'),
})
// 在中间件 (Middleware) 或路由处理程序中
const ip = request.headers.get('x-forwarded-for') ?? '127.0.0.1'
const { success, remaining } = await ratelimit.limit(ip)
if (!success) {
return NextResponse.json({ error: 'Too many requests' }, { status: 429 })
}
```
---
## 环境变量与机密信息
```typescript
// ❌ 错误做法
const API_KEY = 'sk-1234567890abcdef'
// ✅ 正确做法
const API_KEY = process.env.API_KEY
if (!API_KEY) throw new Error('API_KEY not configured')
```
**核心准则:**
- 严禁提交 `.env` 文件(应仅提交包含占位符的 `.env.example`)
- 每个环境应使用不同的密钥
- 定期轮换 (Rotate) 密钥
- 在生产环境中使用机密信息管理器(如 Vault、AWS SSM、Doppler)
- 严禁记录机密信息,或将其包含在错误响应中
---
## 依赖项安全性
```bash
# 定期进行审计
npm audit
npm audit fix
# 检查已知漏洞
npx better-npm-audit audit
# 保持依赖项更新
npx npm-check-updates -u
```
---
## 安全审计报告格式
在进行审查时,请按以下格式输出结果:
```
## 安全审计报告
### 严重 (必须修复)
1. **[A03:注入]** `/api/search` 存在 SQL 注入风险 — 用户输入被直接拼接到查询语句中
- 相关文件: `app/api/search/route.ts:15`
- 修复方案: 使用参数化查询
- 风险等级: 数据库可能遭到全面入侵
### 高危 (应修复)
1. **[A01:访问控制]** DELETE 端点缺少身份验证检查
- 相关文件: `app/api/posts/[id]/route.ts:42`
- 修复方案: 添加身份验证中间件和所有权验证逻辑
### 中危 (建议修复)
1. **[A05:配置错误]** 缺少必要的安全标头 (Security Headers)
- 修复方案: 添加 CSP、HSTS、X-Frame-Options 等标头
### 低危 (仅供参考)
1. **[A06:易受攻击的组件]** 发现 3 个软件包存在已知漏洞
- 处理建议: 运行 `npm audit fix`
```
---
## 受保护的文件模式
在对以下文件进行任何修改之前,应进行仔细核查:
- `.env*` — 包含环境变量密钥的文件
- `auth.ts` / `auth.config.ts` — 身份验证配置
- `middleware.ts` — 路由保护逻辑
- `**/api/auth/**` — 身份验证相关的端点
- `prisma/schema.prisma` — 数据库模式(涉及权限、RLS)
- `next.config.*` — 安全标头、重定向配置
- `package.json` / `package-lock.json` — 涉及依赖项的变更
Files in this skill
- SKILL.md
- _meta.json
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.