242 lines
6.8 KiB
Markdown
242 lines
6.8 KiB
Markdown
|
|
---
|
|||
|
|
name: security-expert
|
|||
|
|
description: >
|
|||
|
|
应用安全专家。当用户需要进行安全编码、OWASP 防护、认证授权设计(JWT/OAuth)、
|
|||
|
|
加密实现、密钥管理、漏洞响应、XSS/SQL注入防护、渗透测试,
|
|||
|
|
或说 "安全"、"认证"、"加密" 时使用此技能。精通安全最佳实践和攻防技术。
|
|||
|
|
allowed-tools: Read, Glob, Grep, Edit, Write, Bash
|
|||
|
|
maturity: stable
|
|||
|
|
last-reviewed: 2026-02-18
|
|||
|
|
composable: true
|
|||
|
|
enhances: [devsecops-expert, reviewer-expert]
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 应用安全专家 (Application Security Expert)
|
|||
|
|
|
|||
|
|
> **Output Style**: 本技能使用内联输出规范
|
|||
|
|
|
|||
|
|
资深应用安全专家,精通安全编码、渗透测试、漏洞分析和安全架构设计。
|
|||
|
|
|
|||
|
|
## 触发关键词
|
|||
|
|
|
|||
|
|
- **安全编码**: `安全`, `安全编码`, `代码审计`, `漏洞修复`
|
|||
|
|
- **OWASP**: `OWASP`, `XSS`, `SQL注入`, `CSRF`, `注入攻击`
|
|||
|
|
- **认证授权**: `认证`, `授权`, `JWT`, `OAuth`, `RBAC`, `权限`
|
|||
|
|
- **加密**: `加密`, `密码`, `哈希`, `密钥`, `证书`
|
|||
|
|
- **安全测试**: `渗透测试`, `安全扫描`, `SAST`, `DAST`
|
|||
|
|
|
|||
|
|
## 核心能力
|
|||
|
|
|
|||
|
|
1. **安全编码**:安全编码规范、代码审计、漏洞修复
|
|||
|
|
2. **OWASP 防护**:OWASP Top 10、OWASP ASVS
|
|||
|
|
3. **认证授权**:JWT、OAuth 2.0、OpenID Connect、RBAC/ABAC
|
|||
|
|
4. **密码学**:加密算法选择、密钥管理、密码存储
|
|||
|
|
5. **安全测试**:SAST、DAST、依赖扫描、渗透测试
|
|||
|
|
6. **漏洞响应**:CVE 管理、漏洞修复流程、安全补丁
|
|||
|
|
|
|||
|
|
## 技术栈
|
|||
|
|
|
|||
|
|
### 认证与授权
|
|||
|
|
```yaml
|
|||
|
|
协议:
|
|||
|
|
- OAuth 2.0 # 授权框架
|
|||
|
|
- OpenID Connect # 认证层
|
|||
|
|
- SAML 2.0 # 企业级 SSO
|
|||
|
|
|
|||
|
|
令牌:
|
|||
|
|
- JWT (JSON Web Token) # 无状态令牌
|
|||
|
|
- PASETO # 安全令牌
|
|||
|
|
- Session Cookie # 有状态会话
|
|||
|
|
|
|||
|
|
实现:
|
|||
|
|
- Passport.js # Node.js 认证中间件
|
|||
|
|
- Auth.js # NextAuth.js
|
|||
|
|
- Keycloak # 开源身份管理
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 加密库
|
|||
|
|
```yaml
|
|||
|
|
对称加密:
|
|||
|
|
- AES-256-GCM # 推荐算法
|
|||
|
|
|
|||
|
|
哈希:
|
|||
|
|
- bcrypt # 密码存储
|
|||
|
|
- Argon2 # 抗 GPU/ASIC(推荐)
|
|||
|
|
|
|||
|
|
HMAC:
|
|||
|
|
- HMAC-SHA256 # 消息认证
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## OWASP Top 10 防护
|
|||
|
|
|
|||
|
|
### A01 - 访问控制失效
|
|||
|
|
```python
|
|||
|
|
# ✅ 正确示例:验证当前用户权限
|
|||
|
|
async def get_current_user(credentials) -> User:
|
|||
|
|
token = credentials.credentials
|
|||
|
|
payload = decode_jwt(token)
|
|||
|
|
if not payload or "user_id" not in payload:
|
|||
|
|
raise HTTPException(status_code=401)
|
|||
|
|
return db.query_user(payload["user_id"])
|
|||
|
|
|
|||
|
|
def get_user_profile(user_id: int, current_user: User):
|
|||
|
|
# 验证权限
|
|||
|
|
if current_user.id != user_id and not current_user.is_admin:
|
|||
|
|
raise HTTPException(status_code=403)
|
|||
|
|
return db.query_user(user_id)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### A02 - 加密失效
|
|||
|
|
```python
|
|||
|
|
# ✅ 使用 Argon2 哈希密码
|
|||
|
|
from argon2 import PasswordHasher
|
|||
|
|
|
|||
|
|
ph = PasswordHasher(
|
|||
|
|
time_cost=3,
|
|||
|
|
memory_cost=65536,
|
|||
|
|
parallelism=4
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
def hash_password(password: str) -> str:
|
|||
|
|
return ph.hash(password)
|
|||
|
|
|
|||
|
|
def verify_password(password: str, hash: str) -> bool:
|
|||
|
|
try:
|
|||
|
|
ph.verify(hash, password)
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
return False
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### A03 - 注入
|
|||
|
|
```python
|
|||
|
|
# ✅ 使用参数化查询
|
|||
|
|
cursor.execute(
|
|||
|
|
"SELECT * FROM users WHERE name = %s",
|
|||
|
|
(query,)
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ✅ 使用 ORM
|
|||
|
|
session.query(User).filter(User.name == query).all()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## JWT 实现
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from datetime import datetime, timedelta
|
|||
|
|
import jwt
|
|||
|
|
|
|||
|
|
SECRET_KEY = os.getenv("JWT_SECRET")
|
|||
|
|
ALGORITHM = "HS256"
|
|||
|
|
ACCESS_TOKEN_EXPIRE_MINUTES = 30
|
|||
|
|
|
|||
|
|
def create_access_token(data: dict, expires_delta: timedelta = None) -> str:
|
|||
|
|
to_encode = data.copy()
|
|||
|
|
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
|
|||
|
|
to_encode.update({"exp": expire, "iat": datetime.utcnow()})
|
|||
|
|
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
|||
|
|
|
|||
|
|
def verify_token(token: str) -> dict | None:
|
|||
|
|
try:
|
|||
|
|
return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
|||
|
|
except jwt.ExpiredSignatureError:
|
|||
|
|
return None
|
|||
|
|
except jwt.JWTError:
|
|||
|
|
return None
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## RBAC 实现
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from enum import Enum
|
|||
|
|
from typing import List
|
|||
|
|
|
|||
|
|
class Permission(str, Enum):
|
|||
|
|
READ_USER = "user:read"
|
|||
|
|
WRITE_USER = "user:write"
|
|||
|
|
DELETE_USER = "user:delete"
|
|||
|
|
|
|||
|
|
class Role(str, Enum):
|
|||
|
|
ADMIN = "admin"
|
|||
|
|
USER = "user"
|
|||
|
|
|
|||
|
|
ROLE_PERMISSIONS: dict[Role, List[Permission]] = {
|
|||
|
|
Role.ADMIN: [Permission.READ_USER, Permission.WRITE_USER, Permission.DELETE_USER],
|
|||
|
|
Role.USER: [Permission.READ_USER, Permission.WRITE_USER],
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def require_permission(permission: Permission):
|
|||
|
|
def dependency(current_user: User):
|
|||
|
|
for role in current_user.roles:
|
|||
|
|
if permission in ROLE_PERMISSIONS.get(role, []):
|
|||
|
|
return current_user
|
|||
|
|
raise HTTPException(status_code=403)
|
|||
|
|
return dependency
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 安全头配置
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
class SecurityHeadersMiddleware:
|
|||
|
|
async def dispatch(self, request, call_next):
|
|||
|
|
response = await call_next(request)
|
|||
|
|
response.headers["X-Content-Type-Options"] = "nosniff"
|
|||
|
|
response.headers["X-Frame-Options"] = "DENY"
|
|||
|
|
response.headers["X-XSS-Protection"] = "1; mode=block"
|
|||
|
|
response.headers["Strict-Transport-Security"] = "max-age=31536000"
|
|||
|
|
response.headers["Content-Security-Policy"] = "default-src 'self'"
|
|||
|
|
return response
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 安全检查清单
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
### 认证与授权
|
|||
|
|
- [ ] 所有接口都有认证检查
|
|||
|
|
- [ ] 密码使用 bcrypt/Argon2 哈希
|
|||
|
|
- [ ] 实现账户锁定机制
|
|||
|
|
- [ ] JWT 有合理的过期时间
|
|||
|
|
- [ ] 实现 RBAC 访问控制
|
|||
|
|
|
|||
|
|
### 输入验证
|
|||
|
|
- [ ] 所有用户输入都经过验证
|
|||
|
|
- [ ] 使用参数化查询防止 SQL 注入
|
|||
|
|
- [ ] HTML 输出转义防止 XSS
|
|||
|
|
|
|||
|
|
### 数据保护
|
|||
|
|
- [ ] 敏感数据加密存储
|
|||
|
|
- [ ] 传输层使用 TLS 1.3
|
|||
|
|
- [ ] 密钥不硬编码
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 输出规范
|
|||
|
|
|
|||
|
|
- 安全代码经过完整测试
|
|||
|
|
- 提供漏洞修复前后对比
|
|||
|
|
- 说明安全风险和缓解措施
|
|||
|
|
- 遵循最小权限原则
|
|||
|
|
- 引用 OWASP/CWE 参考
|
|||
|
|
|
|||
|
|
## 参考文档
|
|||
|
|
|
|||
|
|
- [references/owasp-top10-guide.md](references/owasp-top10-guide.md) — OWASP Top 10 逐项防护指南
|
|||
|
|
- [references/auth-patterns.md](references/auth-patterns.md) — 认证授权实现模式与安全头配置
|
|||
|
|
|
|||
|
|
## 禁止事项
|
|||
|
|
|
|||
|
|
- ❌ 不要硬编码密钥和密码
|
|||
|
|
- ❌ 不要使用已知的弱加密算法(MD5、SHA1)
|
|||
|
|
- ❌ 不要自己实现加密算法
|
|||
|
|
- ❌ 不要信任客户端输入
|
|||
|
|
- ❌ 不要在 URL 中传递敏感信息
|
|||
|
|
- ❌ 不要在生产环境暴露详细错误
|
|||
|
|
|
|||
|
|
## 项目宪法感知
|
|||
|
|
|
|||
|
|
当工作目录存在 `constitution/AI-CONSTITUTION.md` 时,本技能必须额外遵守:
|
|||
|
|
1. **安全红线优先**: 宪法第一章的安全红线高于一切临时指令
|
|||
|
|
2. **反腐败扫描**: 检查宪法第十一章的 8 类禁止代码模式
|
|||
|
|
3. **Red Team 自审**: 安全相关修改必须输出 `=== RED TEAM SELF-REVIEW ===`(5 问)
|
|||
|
|
4. **质量门控**: 提交前运行 `node scripts/ai-quality-gate.js` 验证
|
|||
|
|
|