Security patterns for session keys, caching, logging, and environment variables. Use when implementing authentication, caching sensitive data, or setting up logging...
Common pitfalls and correct patterns for security.
Verify no private keys stored in plaintext.
Ensure sensitive data not cached inappropriately.
Confirm no secrets in logs.
// ❌ NEVER store private keys
localStorage.setItem('privateKey', key); // CATASTROPHIC
// ✅ Use session keys with limited permissions
interface SessionKey {
address: Address;
permissions: Permission[];
expiresAt: Date;
maxPerTrade: bigint;
}
// ✅ AES-256-GCM for any stored credentials
import { createCipheriv, randomBytes } from 'crypto';
const iv = randomBytes(16);
const cipher = createCipheriv('aes-256-gcm', key, iv);
// ✅ Audit logging for all key operations
await auditLog.create({
action: 'SESSION_KEY_CREATED',
userId,
metadata: { permissions, expiresAt },
});
// Frontend (Vite)
const apiUrl = import.meta.env.VITE_API_URL; // ✅ VITE_ prefix required
// ❌ process.env.API_URL won't work in frontend
// Backend
const dbUrl = process.env.DATABASE_URL;
// ❌ NEVER log secrets
console.log('Config:', config); // May contain secrets!
// ✅ Log safely
console.log('Config loaded for:', config.environment);
// ✅ Server-side cache for expensive computations
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 based on data freshness needs
const CACHE_TTL = {
tokenPrice: 10_000, // 10s - prices change fast
poolReserves: 5_000, // 5s - critical for swaps
gasPrice: 15_000, // 15s
userBalance: 30_000, // 30s
tokenMetadata: 3600_000, // 1 hour - rarely changes
};
// ❌ Never cache user-specific sensitive data
cache.set(`user:${userId}:privateKey`, key); // NEVER!
// ✅ Structured logging (JSON format)
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,
}));
},
};
// ✅ Include context
logger.info('Trade executed', {
userId: 'user123',
txHash: '0x...',
chain: 'ethereum',
profit: '12.34',
});
// ❌ NEVER log secrets
logger.info('Config', { apiKey: process.env.API_KEY }); // NEVER!
// ✅ Audit logging for sensitive operations
await auditLog.create({
action: 'TRADE_EXECUTED',
userId,
before: previousState,
after: newState,
timestamp: new Date(),
metadata: { txHash, chain },
});