feat: add enhanced security validation and timing protection

Security Enhancements:
- Add salt entropy validation (minimum 16 unique bytes for 64-byte salts)
- Expand secure logging patterns to catch more sensitive data types
  (fingerprint, mac, hash patterns)
- Implement random timing delays in verifyAuthProof() to mask execution timing
- Revert sanitizeMessage() to working regex-based approach

Validation Improvements:
- validateSalt() now checks both size and entropy quality
- secureLog.sanitizeContext() enhanced with additional sensitive patterns
- Added timing attack protection with 5-25ms random delays
This commit is contained in:
lockbitchat
2025-08-26 19:58:45 -04:00
parent 1e270fb4b8
commit 984564fae6

View File

@@ -753,6 +753,19 @@ class EnhancedSecureCryptoUtils {
} }
}; };
static validateSalt(salt) {
if (!salt || salt.length !== 64) {
throw new Error('Salt must be exactly 64 bytes');
}
const uniqueBytes = new Set(salt);
if (uniqueBytes.size < 16) {
throw new Error('Salt has insufficient entropy');
}
return true;
}
// Secure logging without data leaks // Secure logging without data leaks
static secureLog = { static secureLog = {
logs: [], logs: [],
@@ -786,12 +799,19 @@ class EnhancedSecureCryptoUtils {
}, },
sanitizeContext(context) { sanitizeContext(context) {
const sensitivePatterns = [
/key/i, /secret/i, /password/i, /token/i, /signature/i,
/challenge/i, /proof/i, /salt/i, /iv/i, /nonce/i, /hash/i,
/fingerprint/i, /mac/i
];
const sanitized = {}; const sanitized = {};
for (const [key, value] of Object.entries(context)) { for (const [key, value] of Object.entries(context)) {
if (key.toLowerCase().includes('key') || const isSensitive = sensitivePatterns.some(pattern =>
key.toLowerCase().includes('secret') || pattern.test(key) || (typeof value === 'string' && pattern.test(value))
key.toLowerCase().includes('password') || );
key.toLowerCase().includes('token')) {
if (isSensitive) {
sanitized[key] = '[REDACTED]'; sanitized[key] = '[REDACTED]';
} else if (typeof value === 'string' && value.length > 100) { } else if (typeof value === 'string' && value.length > 100) {
sanitized[key] = value.substring(0, 100) + '...[TRUNCATED]'; sanitized[key] = value.substring(0, 100) + '...[TRUNCATED]';
@@ -1725,6 +1745,7 @@ class EnhancedSecureCryptoUtils {
// Verify mutual authentication proof // Verify mutual authentication proof
static async verifyAuthProof(proof, challenge, publicKey) { static async verifyAuthProof(proof, challenge, publicKey) {
try { try {
await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 20) + 5));
// Assert the public key is valid and has the correct usage // Assert the public key is valid and has the correct usage
EnhancedSecureCryptoUtils.assertCryptoKey(publicKey, 'ECDSA', ['verify']); EnhancedSecureCryptoUtils.assertCryptoKey(publicKey, 'ECDSA', ['verify']);