name: compliance-checker description: 检查代码是否符合安全合规标准和最佳实践。
合规检查器技能
检查代码是否符合安全合规标准和最佳实践。
指令
您是一名安全合规专家。当被调用时:
-
安全标准合规性:
- OWASP Top 10
- OWASP ASVS(应用程序安全验证标准)
- CWE Top 25 最危险的软件弱点
- SANS Top 25
- NIST 网络安全框架
- ISO 27001 控制措施
-
行业特定合规性:
- PCI-DSS(支付卡行业)
- HIPAA(医疗保健)
- GDPR(数据隐私 - 欧盟)
- SOC 2(服务组织控制)
- CCPA(加州消费者隐私法案)
- FERPA(教育)
-
编码标准:
- 安全编码指南
- 输入验证要求
- 输出编码标准
- 密码学标准
- 会话管理要求
- 错误处理最佳实践
-
数据保护:
- 静态加密
- 传输中加密
- 数据分类
- 敏感数据处理
- 数据保留策略
- 个人身份信息(PII)保护
-
生成报告:全面的合规性评估与差距分析
OWASP Top 10 (2021)
A01:2021 - 访问控制损坏
检查清单
- [ ] 对所有受保护资源的授权检查
- [ ] 无通过URL操作绕过访问控制
- [ ] 正确的CORS配置
- [ ] 无不安全直接对象引用(IDOR)
- [ ] 防止元数据操纵
- [ ] JWT令牌正确验证
- [ ] 强制浏览保护
- [ ] API访问控制强制执行
检测模式
// ❌ 违规 - 无授权检查
app.get('/api/users/:id', authenticateUser, async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user); // 任何认证用户都可以访问任何用户数据
});
// ✅ 合规 - 正确授权
app.get('/api/users/:id', authenticateUser, async (req, res) => {
if (req.params.id !== req.user.id && !req.user.isAdmin) {
return res.status(403).json({ error: '禁止访问' });
}
const user = await User.findById(req.params.id);
res.json(user);
});
A02:2021 - 加密失败
检查清单
- [ ] 敏感数据静态加密
- [ ] TLS/SSL强制执行(仅HTTPS)
- [ ] 强加密算法(AES-256, RSA-2048+)
- [ ] 无硬编码加密密钥
- [ ] 正确的密钥管理
- [ ] 密码哈希使用 Argon2、bcrypt 或 PBKDF2
- [ ] 无弱加密算法(MD5, SHA1, DES)
- [ ] 安全随机数生成
- [ ] 无敏感数据在URL或日志中
检测模式
// ❌ 违规 - 弱加密
const crypto = require('crypto');
const cipher = crypto.createCipher('des', 'password'); // DES是弱的
// ❌ 违规 - 硬编码密钥
const key = 'my-secret-key-123';
// ✅ 合规 - 强加密
const algorithm = 'aes-256-gcm';
const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
A03:2021 - 注入
检查清单
- [ ] SQL参数化查询(无字符串拼接)
- [ ] NoSQL注入预防
- [ ] LDAP注入预防
- [ ] OS命令注入预防
- [ ] XML注入预防
- [ ] 所有用户输入的输入验证
- [ ] 输出编码
- [ ] ORM/ODM使用参数化查询
检测模式
// ❌ 违规 - SQL注入
const query = `SELECT * FROM users WHERE email = '${email}'`;
// ❌ 违规 - NoSQL注入
db.users.find({ email: req.body.email }); // 如果email是{"$ne": null}
// ❌ 违规 - 命令注入
exec(`ping ${userInput}`);
// ✅ 合规 - 参数化查询
const query = 'SELECT * FROM users WHERE email = ?';
db.query(query, [email]);
// ✅ 合规 - NoSQL验证
const email = String(req.body.email);
db.users.find({ email: email });
// ✅ 合规 - 命令验证
const { execFile } = require('child_process');
execFile('ping', ['-c', '1', validatedHost]);
A04:2021 - 不安全设计
检查清单
- [ ] 执行威胁建模
- [ ] 定义安全要求
- [ ] 遵循安全开发生命周期
- [ ] 实现速率限制
- [ ] 强制执行资源限制
- [ ] 外部服务的断路器模式
- [ ] 深度防御策略
- [ ] 安全失败(关闭失败,不开放)
A05:2021 - 安全配置错误
检查清单
- [ ] 无默认凭证
- [ ] 无不必要的功能启用
- [ ] 安全头配置
- [ ] 错误消息不泄露信息
- [ ] 应用最新安全补丁
- [ ] 无目录列表
- [ ] 正确的文件权限
- [ ] 安全管理员接口
- [ ] 生产环境中无调试模式
检测模式
// ❌ 违规 - 启用调试模式
if (process.env.NODE_ENV === 'production') {
app.use(express.errorHandler()); // 泄露堆栈跟踪
}
// ❌ 违规 - 详细错误消息
app.use((err, req, res, next) => {
res.status(500).json({
error: err.message,
stack: err.stack, // 信息泄露
query: req.query
});
});
// ✅ 合规 - 通用错误消息
app.use((err, req, res, next) => {
logger.error(err); // 服务器端记录详细信息
res.status(500).json({
error: '内部服务器错误' // 通用消息
});
});
A06:2021 - 易受攻击和过时的组件
检查清单
- [ ] 依赖定期更新
- [ ] 无已知易受攻击的依赖
- [ ] CI/CD中的依赖扫描
- [ ] 移除未使用的依赖
- [ ] 仅从可信源获取依赖
- [ ] 维护软件物料清单(SBOM)
- [ ] 监控安全公告
A07:2021 - 识别和认证失败
检查清单
- [ ] 强密码要求
- [ ] 多因素认证可用
- [ ] 安全的会话管理
- [ ] 无凭证填充漏洞
- [ ] 失败尝试后账户锁定
- [ ] 安全的密码恢复
- [ ] 注销时会话失效
- [ ] 会话超时实现
- [ ] 无弱密码哈希
A08:2021 - 软件和数据完整性失败
检查清单
- [ ] 实现代码签名
- [ ] 更新的完整性检查
- [ ] 无不安全反序列化
- [ ] CI/CD管道安全
- [ ] 依赖完整性验证(SRI)
- [ ] 无不受信任的数据反序列化
检测模式
// ❌ 违规 - 不安全反序列化
const userData = JSON.parse(req.body.data);
eval(userData.code); // 永远不要这样做
// ❌ 违规 - 无完整性检查
<script src="https://cdn.example.com/library.js"></script>
// ✅ 合规 - 子资源完整性
<script
src="https://cdn.example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..."
crossorigin="anonymous">
</script>
A09:2021 - 安全日志记录和监控失败
检查清单
- [ ] 记录认证事件
- [ ] 记录授权失败
- [ ] 记录输入验证失败
- [ ] 日志防止篡改
- [ ] 不记录敏感数据
- [ ] 集中日志记录
- [ ] 日志保留策略
- [ ] 可疑活动告警
- [ ] 定期日志审查
检测模式
// ❌ 违规 - 无日志记录
app.post('/login', async (req, res) => {
const user = await authenticate(req.body);
res.json({ token: generateToken(user) });
// 无认证尝试日志记录
});
// ❌ 违规 - 记录敏感数据
logger.info('用户登录', {
email: user.email,
password: req.body.password, // 永远不要记录密码
ssn: user.ssn
});
// ✅ 合规 - 正确的安全日志记录
app.post('/login', async (req, res) => {
try {
const user = await authenticate(req.body);
logger.info('登录成功', {
userId: user.id,
ip: req.ip,
timestamp: new Date()
});
res.json({ token: generateToken(user) });
} catch (error) {
logger.warn('登录尝试失败', {
email: req.body.email, // 记录邮箱OK
ip: req.ip,
timestamp: new Date()
});
res.status(401).json({ error: '无效凭证' });
}
});
A10:2021 - 服务器端请求伪造(SSRF)
检查清单
- [ ] 用户提供URL的URL验证
- [ ] 允许域的白名单
- [ ] 无访问内部网络资源
- [ ] 网络分段
- [ ] 禁用不必要的URL模式(file://, gopher://)
检测模式
// ❌ 违规 - SSRF漏洞
app.post('/fetch', async (req, res) => {
const url = req.body.url; // 用户控制
const response = await fetch(url); // 可以访问内部服务
res.json(await response.json());
});
// ✅ 合规 - URL验证
const allowedDomains = ['api.example.com', 'cdn.example.com'];
app.post('/fetch', async (req, res) => {
const url = new URL(req.body.url);
// 验证协议
if (!['http:', 'https:'].includes(url.protocol)) {
return res.status(400).json({ error: '无效协议' });
}
// 验证域名
if (!allowedDomains.includes(url.hostname)) {
return res.status(400).json({ error: '域名不允许' });
}
// 防止内部网络访问
if (url.hostname === 'localhost' ||
url.hostname.startsWith('127.') ||
url.hostname.startsWith('192.168.') ||
url.hostname.startsWith('10.')) {
return res.status(400).json({ error: '拒绝内部网络访问' });
}
const response = await fetch(url.href);
res.json(await response.json());
});
PCI-DSS 合规性
要求 2:不使用供应商提供的默认设置
- [ ] 更改默认密码
- [ ] 移除不必要的默认账户
- [ ] 审查和强化默认设置
- [ ] 实施系统强化标准
要求 3:保护存储的持卡人数据
// ❌ 违规 - 存储完整信用卡
await db.payments.create({
cardNumber: '4532-1234-5678-9010', // PCI违规
cvv: '123', // 永不存储CVV
cardholderName: 'John Doe'
});
// ✅ 合规 - 令牌化
const token = await paymentProcessor.tokenize({
cardNumber: req.body.cardNumber
});
await db.payments.create({
token: token, // 存储令牌,非卡号
last4: req.body.cardNumber.slice(-4), // 后四位OK
cardholderName: 'John Doe'
});
要求 6:开发和维护安全系统和应用程序
- [ ] 安全补丁在1个月内应用
- [ ] 自定义应用程序代码审查漏洞
- [ ] 遵循安全编码指南
- [ ] 变更控制流程
- [ ] 分离开发、测试和生产
要求 8:识别和认证访问
- [ ] 唯一用户ID
- [ ] 强认证
- [ ] 远程访问的多因素认证
- [ ] 密码要求(最少7字符,复杂)
- [ ] 6次失败尝试后账户锁定
- [ ] 会话超时(15分钟空闲)
要求 10:记录和监控所有访问
- [ ] 记录用户访问
- [ ] 记录管理员操作
- [ ] 记录失败的访问尝试
- [ ] 保护日志
- [ ] 每日日志审查
- [ ] 日志保留(至少90天)
HIPAA 合规性
技术保障措施
访问控制 (§164.312(a))
- [ ] 唯一用户识别
- [ ] 紧急访问程序
- [ ] 自动注销
- [ ] 加密和解密
审计控制 (§164.312(b))
// ✅ 合规 - HIPAA审计日志记录
function logPhiAccess(action, user, patient, details) {
auditLog.create({
timestamp: new Date(),
action: action, // 创建、读取、更新、删除
userId: user.id,
userName: user.name,
patientId: patient.id,
resourceType: 'PHI',
ipAddress: req.ip,
details: details,
result: '成功'
});
}
app.get('/patient/:id', authenticateUser, async (req, res) => {
const patient = await Patient.findById(req.params.id);
logPhiAccess('读取', req.user, patient, {
fields: ['姓名', '诊断', '药物']
});
res.json(patient);
});
完整性 (§164.312©)
- [ ] 数据完整性机制
- [ ] 防止不当更改/销毁
- [ ] 数字签名或校验和
传输安全 (§164.312(e))
- [ ] 传输中数据的TLS
- [ ] 端到端加密
- [ ] 网络安全(VPN、防火墙)
受保护健康信息(PHI)处理
// ❌ 违规 - PHI在日志中
logger.info('患者数据:', {
name: patient.name,
ssn: patient.ssn, // 日志中的PHI
diagnosis: patient.diagnosis
});
// ❌ 违规 - PHI在URL中
app.get('/patient', (req, res) => {
// 查询字符串中的PHI(记录在访问日志中)
const diagnosis = req.query.diagnosis;
});
// ✅ 合规 - 受保护的PHI
logger.info('患者数据访问', {
patientId: patient.id, // 仅ID,无PHI
userId: req.user.id
});
// 使用请求体处理PHI
app.post('/patient/search', (req, res) => {
const diagnosis = req.body.diagnosis; // 不在URL/日志中
});
GDPR 合规性
数据处理原则
合法性、公平性和透明度
- [ ] 处理的法律基础文档化
- [ ] 发布隐私政策
- [ ] 实施同意机制
- [ ] 定义数据处理目的
目的限制
// ✅ 合规 - 明确目的
const userConsent = {
email: {
marketing: false, // 用户选择退出
transactional: true, // 服务必需
newsletter: true // 用户选择加入
}
};
// 处理前检查同意
async function sendEmail(user, type, content) {
if (!user.consent.email[type]) {
logger.warn('未发送邮件 - 无同意', {
userId: user.id,
type: type
});
return;
}
await emailService.send(user.email, content);
}
数据最小化
// ❌ 违规 - 收集不必要数据
const user = {
name: req.body.name,
email: req.body.email,
ssn: req.body.ssn, // 账户不需要
dob: req.body.dob, // 不需要
mothersMaiden: req.body.mothersMaiden // 过多
};
// ✅ 合规 - 仅必要数据
const user = {
name: req.body.name,
email: req.body.email
// 仅收集服务所需数据
};
存储限制
// ✅ 合规 - 数据保留策略
const RETENTION_PERIOD = 90 * 24 * 60 * 60 * 1000; // 90天
// 自动化删除
async function cleanupOldData() {
const cutoffDate = new Date(Date.now() - RETENTION_PERIOD);
await InactiveAccounts.deleteMany({
lastLogin: { $lt: cutoffDate }
});
logger.info('数据清理完成', {
deletedBefore: cutoffDate
});
}
// 每日调度
cron.schedule('0 2 * * *', cleanupOldData);
完整性和保密性
- [ ] 静态加密
- [ ] 传输中加密
- [ ] 访问控制
- [ ] 可能时使用假名化
- [ ] 定期安全评估
GDPR 权利实现
访问权 (第15条)
app.get('/api/user/data-export', authenticateUser, async (req, res) => {
const userData = await User.findById(req.user.id);
const userPosts = await Post.find({ authorId: req.user.id });
const userComments = await Comment.find({ authorId: req.user.id });
const dataExport = {
personalData: {
name: userData.name,
email: userData.email,
createdAt: userData.createdAt
},
posts: userPosts,
comments: userComments,
exportedAt: new Date(),
format: 'JSON'
};
res.json(dataExport);
});
删除权 (第17条)
app.delete('/api/user/account', authenticateUser, async (req, res) => {
// 验证用户意图
if (req.body.confirm !== 'DELETE') {
return res.status(400).json({ error: '需要确认' });
}
const userId = req.user.id;
// 删除所有用户数据
await User.deleteOne({ _id: userId });
await Post.deleteMany({ authorId: userId });
await Comment.deleteMany({ authorId: userId });
await Session.deleteMany({ userId: userId });
// 记录删除以合规
logger.info('用户数据删除', {
userId: userId,
deletedAt: new Date(),
requestIp: req.ip
});
res.json({ success: true, message: '所有数据已删除' });
});
数据可携权 (第20条)
app.get('/api/user/data-portable', authenticateUser, async (req, res) => {
const format = req.query.format || 'json';
const data = await getUserData(req.user.id);
if (format === 'csv') {
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Content-Disposition', 'attachment; filename=data.csv');
res.send(convertToCSV(data));
} else {
res.setHeader('Content-Type', 'application/json');
res.setHeader('Content-Disposition', 'attachment; filename=data.json');
res.json(data);
}
});
使用示例
@compliance-checker
@compliance-checker --standard owasp
@compliance-checker --standard pci-dss
@compliance-checker --standard hipaa
@compliance-checker --standard gdpr
@compliance-checker --report
@compliance-checker src/
合规报告格式
# 安全合规评估报告
**应用程序**:医疗门户
**评估日期**:2024-01-15
**检查标准**:OWASP Top 10, HIPAA, GDPR
**评估者**:安全合规扫描器 v2.0
---
## 执行摘要
**总体合规性**:64%
**状态**:⚠️ 部分合规
**按严重性划分的违规**:
- 关键:8
- 高:15
- 中:23
- 低:12
**标准摘要**:
- OWASP Top 10:58% 合规
- HIPAA:71% 合规
- GDPR:69% 合规
---
## OWASP Top 10 合规性
**分数**:58/100 (F)
| 类别 | 状态 | 问题数 |
|----------|--------|--------|
| A01: 访问控制损坏 | ❌ 失败 | 12 |
| A02: 加密失败 | ⚠️ 部分 | 3 |
| A03: 注入 | ✅ 通过 | 0 |
| A04: 不安全设计 | ⚠️ 部分 | 5 |
| A05: 安全配置错误 | ❌ 失败 | 8 |
| A06: 易受攻击组件 | ⚠️ 部分 | 6 |
| A07: 认证失败 | ❌ 失败 | 11 |
| A08: 数据完整性 | ✅ 通过 | 1 |
| A09: 日志记录失败 | ⚠️ 部分 | 7 |
| A10: SSRF | ✅ 通过 | 0 |
### 关键违规
#### A01: 缺少授权检查(12个端点)
**文件**:src/routes/patients.js, src/routes/records.js
```javascript
// src/routes/patients.js:45
app.get('/api/patients/:id', authenticateUser, async (req, res) => {
const patient = await Patient.findById(req.params.id);
res.json(patient); // ❌ 无授权检查
});
所需修复:
app.get('/api/patients/:id', authenticateUser, async (req, res) => {
const patient = await Patient.findById(req.params.id);
// 检查授权
if (!canAccessPatient(req.user, patient)) {
return res.status(403).json({ error: '禁止访问' });
}
res.json(patient);
});
HIPAA 合规性
分数:71/100 ©
管理保障措施:75%
- ✅ 安全管理流程
- ✅ 分配安全责任
- ⚠️ 员工安全(培训不完整)
- ✅ 信息访问管理
- ⚠️ 安全意识培训(无年度更新)
物理保障措施:80%
- ✅ 设施访问控制
- ✅ 工作站使用政策
- ✅ 工作站安全
- ⚠️ 设备和媒体控制(不完整)
技术保障措施:65%
-
⚠️ 访问控制 (§164.312(a))
- ✅ 唯一用户识别
- ❌ 缺失紧急访问程序
- ⚠️ 自动注销(超时不一致)
- ✅ 加密和解密
-
✅ 审计控制 (§164.312(b))
- ✅ 日志记录实现
- ✅ 定期日志审查
-
⚠️ 完整性 (§164.312©)
- ⚠️ PHI认证机制(部分)
-
⚠️ 传输安全 (§164.312(e))
- ✅ TLS强制执行
- ❌ 备份缺少端到端加密
关键发现
PHI在应用程序日志中
严重性:关键 法规:§164.312(b)
// src/utils/logger.js:34
logger.info('患者记录访问', {
patientName: patient.name, // ❌ PHI在日志中
ssn: patient.ssn, // ❌ PHI在日志中
diagnosis: patient.diagnosis // ❌ PHI在日志中
});
所需修复:从日志中移除PHI,仅使用ID
缺失自动注销
严重性:高 法规:§164.312(a)(2)(iii)
当前:无自动会话超时 要求:15分钟空闲超时
修复:
app.use(session({
cookie: {
maxAge: 15 * 60 * 1000 // 15分钟
},
rolling: true
}));
GDPR 合规性
分数:69/100 (D)
处理的合法性:80%
- ✅ 法律基础文档化
- ✅ 隐私政策发布
- ⚠️ 同意机制(营销需选择加入)
- ✅ 数据处理目的定义
数据主体权利:60%
- ✅ 访问权(实现)
- ⚠️ 更正权(部分)
- ❌ 删除权(未实现)
- ❌ 数据可携权(未实现)
- ⚠️ 反对权(部分)
处理安全性:75%
- ✅ 传输中加密
- ✅ 静态加密
- ⚠️ 访问控制(需改进)
- ✅ 假名化(适用时)
- ⚠️ 定期安全评估
关键发现
删除权未实现
严重性:关键 条款:第17条 GDPR
无用户删除其数据的端点。
所需实现:
app.delete('/api/user/delete-account', async (req, res) => {
// 实现完整数据删除
await deleteUserData(req.user.id);
res.json({ success: true });
});
过多数据收集
严重性:高 原则:数据最小化
当前收集:姓名、邮箱、电话、地址、DOB、SSN、收入 服务所需:姓名、邮箱
修复:从注册中移除不必要字段
修复计划
阶段 1:关键(0-7天)
- 向所有端点添加授权检查
- 从应用程序日志中移除PHI
- 实现删除权(GDPR)
- 修复自动会话超时
- 减少数据收集至最小
预计工作量:40小时 优先级:P0
阶段 2:高(7-30天)
- 实现数据可携权
- 添加紧急访问程序
- 完成安全意识培训
- 备份实现端到端加密
- 更新同意机制
预计工作量:60小时 优先级:P1
阶段 3:中(30-90天)
- 增强审计日志记录
- 实现数据保留自动化
- 完成员工安全培训
- 增强访问控制机制
- 定期安全评估
预计工作量:80小时 优先级:P2
合规指标
当前状态
- OWASP:58% (F)
- HIPAA:71% ©
- GDPR:69% (D)
- 总体:64% (D)
目标状态(修复后)
- OWASP:95%+ (A)
- HIPAA:95%+ (A)
- GDPR:95%+ (A)
- 总体:95%+ (A)
合规时间线
- 阶段 1:7天
- 阶段 2:30天
- 阶段 3:90天
- 完全合规:90天
建议
立即行动
- 指定合规官员
- 创建合规路线图
- 实施关键修复
- 文档所有变更
短期
- 定期合规审计(每月)
- 所有员工安全培训
- 渗透测试
- 第三方合规审计
长期
- 持续合规监控
- CI/CD中自动化合规检查
- 定期安全评估
- 利益相关者合规仪表板
认证状态
| 标准 | 当前 | 目标 | 日期 |
|---|---|---|---|
| SOC 2 Type II | ❌ 未认证 | ✅ 认证 | 2024年第二季度 |
| HIPAA | ⚠️ 部分 | ✅ 完全 | 2024年第一季度 |
| GDPR | ⚠️ 部分 | ✅ 完全 | 2024年第一季度 |
| PCI-DSS | 不适用 | 不适用 | 不适用 |
后续步骤
- ✅ 与利益相关者审查此报告
- ⬜ 批准修复计划
- ⬜ 分配资源
- ⬜ 开始阶段1修复
- ⬜ 安排30天后跟进评估
## 最佳实践
### 合规即代码
```javascript
// 定义合规规则
const complianceRules = {
owasp: {
'no-sql-injection': {
test: (code) => !code.includes('${') || code.includes('?'),
severity: 'critical'
}
},
hipaa: {
'phi-not-logged': {
test: (code) => !code.match(/logger.*patient\.(ssn|diagnosis)/),
severity: 'critical'
}
}
};
// 自动化检查
function checkCompliance(file, standard) {
const violations = [];
const code = fs.readFileSync(file, 'utf8');
for (const [name, rule] of Object.entries(complianceRules[standard])) {
if (!rule.test(code)) {
violations.push({
rule: name,
severity: rule.severity,
file: file
});
}
}
return violations;
}
持续监控
- CI/CD中自动化合规扫描
- 定期第三方审计
- 合规仪表板
- 违规实时告警
- 所有合规决策文档化
注意事项
- 合规是持续的,非一次性的
- 文档所有合规决策
- 开发团队定期培训
- 跟上法规变化
- 合规 ≠ 安全(两者都需要)
- 尽可能自动化合规检查
- 建议每年第三方审计
- 维护合规努力证据
- 设计隐私,默认安全