name: pitfalls-security description: “安全模式:会话密钥、缓存、日志和环境变量。适用于实现身份验证、缓存敏感数据或设置日志记录时。触发条件:会话密钥、私钥、缓存、日志、密钥、环境变量。”
安全陷阱
常见的安全陷阱及正确模式。
何时使用
- 实现会话密钥管理
- 缓存数据(尤其是敏感数据)
- 设置结构化日志记录
- 处理环境变量
- 审查安全敏感代码
工作流程
步骤 1:检查密钥存储
验证没有以明文存储私钥。
步骤 2:验证缓存安全性
确保敏感数据未被不恰当地缓存。
步骤 3:检查日志记录
确认日志中没有密钥。
会话密钥安全
// ❌ 切勿存储私钥
localStorage.setItem('privateKey', key); // 灾难性的
// ✅ 使用具有有限权限的会话密钥
interface SessionKey {
address: Address;
permissions: Permission[];
expiresAt: Date;
maxPerTrade: bigint;
}
// ✅ 对任何存储的凭证使用 AES-256-GCM
import { createCipheriv, randomBytes } from 'crypto';
const iv = randomBytes(16);
const cipher = createCipheriv('aes-256-gcm', key, iv);
// ✅ 对所有密钥操作进行审计日志记录
await auditLog.create({
action: 'SESSION_KEY_CREATED',
userId,
metadata: { permissions, expiresAt },
});
环境变量
// 前端(Vite)
const apiUrl = import.meta.env.VITE_API_URL; // ✅ 需要 VITE_ 前缀
// ❌ process.env.API_URL 在前端无效
// 后端
const dbUrl = process.env.DATABASE_URL;
// ❌ 切勿记录密钥
console.log('Config:', config); // 可能包含密钥!
// ✅ 安全地记录
console.log('Config loaded for:', config.environment);
缓存策略
// ✅ 服务器端缓存用于昂贵计算
const priceCache = new Map<string, { value: number; expires: number }>();
function getCachedPrice(token: string): number | null {
const cached = priceCache.get(token);
if (cached && cached.expires > Date.now()) {
return cached.value;
}
return null;
}
// ✅ 基于数据新鲜度需求的 TTL
const CACHE_TTL = {
tokenPrice: 10_000, // 10秒 - 价格变化快
poolReserves: 5_000, // 5秒 - 对交换至关重要
gasPrice: 15_000, // 15秒
userBalance: 30_000, // 30秒
tokenMetadata: 3600_000, // 1小时 - 很少变化
};
// ❌ 切勿缓存用户特定的敏感数据
cache.set(`user:${userId}:privateKey`, key); // 绝对不要!
结构化日志记录
// ✅ 结构化日志记录(JSON 格式)
const logger = {
info: (message: string, context?: object) => {
console.log(JSON.stringify({
level: 'info',
message,
timestamp: new Date().toISOString(),
...context,
}));
},
error: (message: string, error: Error, context?: object) => {
console.error(JSON.stringify({
level: 'error',
message,
error: error.message,
stack: error.stack,
timestamp: new Date().toISOString(),
...context,
}));
},
};
// ✅ 包含上下文
logger.info('交易已执行', {
userId: 'user123',
txHash: '0x...',
chain: 'ethereum',
profit: '12.34',
});
// ❌ 切勿记录密钥
logger.info('配置', { apiKey: process.env.API_KEY }); // 绝对不要!
审计日志记录
// ✅ 对敏感操作进行审计日志记录
await auditLog.create({
action: 'TRADE_EXECUTED',
userId,
before: previousState,
after: newState,
timestamp: new Date(),
metadata: { txHash, chain },
});
快速检查清单
- [ ] localStorage 中没有私钥
- [ ] 会话密钥具有过期时间和限制
- [ ] 对存储的凭证使用 AES-256-GCM
- [ ] 对敏感操作进行审计日志记录
- [ ] console.log 中没有密钥
- [ ] 敏感数据未被不恰当地缓存
- [ ] 前端环境变量使用 VITE_ 前缀