secure-express-setup
Version:
Military-grade one-command security setup for Express.js applications
93 lines (79 loc) • 3.19 kB
JavaScript
// lib/secretsDetection.js
function setupSecretsDetection() {
const secretPatterns = [
// API keys (but allow short tokens for testing)
/(?:api[_-]?key|apikey)["\s:=]+([a-zA-Z0-9_\-]{20,})/gi,
// Passwords
/(?:password|passwd|pwd)["\s:=]+([^\s"']{8,})/gi,
// Generic secrets (but not JWT-like tokens in test env)
/(?:secret)["\s:=]+([a-zA-Z0-9_\-]{20,})/gi,
// AWS keys
/(?:aws_access_key_id|aws_secret_access_key)["\s:=]+([A-Z0-9]{20,})/gi,
// Private keys
/(?:private[_-]?key)["\s:=]+([^\s"']{20,})/gi,
// Database connection strings
/(?:mongodb|postgres|mysql):\/\/[^:]+:[^@]+@/gi,
// Email with password
/smtp:[^:]+:[^@]+@/gi
];
// Patterns to whitelist (allowed even if they look like secrets)
const whitelistPatterns = [
// JWT tokens in test responses
/eyJ[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*/g,
// Test/demo tokens
/test[-_]token/i,
/demo[-_]key/i,
// Encrypted data (from our encryption helper)
/U2FsdGVkX1[+/A-Za-z0-9]+/g
];
return (req, res, next) => {
const originalJson = res.json.bind(res);
res.json = function(data) {
// Skip secret detection for certain paths or in test mode
const skipPaths = ['/test/generate-token', '/test/encrypt', '/test/decrypt'];
const isTestPath = skipPaths.some(path => req.path.includes(path));
if (process.env.NODE_ENV === 'test' || isTestPath) {
// In test mode, log but don't block
const jsonString = JSON.stringify(data);
let foundSecret = false;
for (const pattern of secretPatterns) {
if (pattern.test(jsonString)) {
// Check if it's whitelisted
const isWhitelisted = whitelistPatterns.some(whitelist =>
whitelist.test(jsonString)
);
if (!isWhitelisted) {
console.warn('⚠️ Potential secret detected in test response (not blocked)');
foundSecret = true;
}
}
}
if (foundSecret && process.env.DEBUG_SECRETS) {
console.log('Debug - Response data:', JSON.stringify(data, null, 2));
}
return originalJson(data);
}
// Production mode: strict checking
const jsonString = JSON.stringify(data);
for (const pattern of secretPatterns) {
if (pattern.test(jsonString)) {
// Check if it's whitelisted
const isWhitelisted = whitelistPatterns.some(whitelist =>
whitelist.test(jsonString)
);
if (!isWhitelisted) {
console.error('🚨 CRITICAL: Secret detected in response! Blocking...');
// Sanitize the response instead of blocking
return originalJson({
error: 'Internal server error',
message: 'Security policy violation detected'
});
}
}
}
return originalJson(data);
};
next();
};
}
module.exports = setupSecretsDetection;