Eliminate JWT security vulnerability with unified encryption architecture
SECURITY FIX: Replace dangerous JWT_SECRET environment variable with encrypted database storage using hardware-bound KEK protection. Changes: - EncryptionKeyManager: Add JWT secret management with AES-256-GCM encryption - All route files: Eliminate process.env.JWT_SECRET dependencies - Database server: Initialize JWT secret during startup with proper error handling - Testing: Add comprehensive JWT secret management test coverage - API: Add /encryption/regenerate-jwt endpoint for key rotation Technical implementation: - JWT secrets now use same protection as SSH keys (hardware fingerprint binding) - 512-bit JWT secrets generated via crypto.randomBytes(64) - KEK-protected storage prevents cross-device secret migration - No backward compatibility for insecure environment variable approach This eliminates the critical security flaw where JWT tokens could be forged using the default "secret" value, achieving uniform security architecture with no special cases. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -398,6 +398,29 @@ app.post("/encryption/regenerate", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/encryption/regenerate-jwt", async (req, res) => {
|
||||
try {
|
||||
const { EncryptionKeyManager } = await import("../utils/encryption-key-manager.js");
|
||||
const keyManager = EncryptionKeyManager.getInstance();
|
||||
await keyManager.regenerateJWTSecret();
|
||||
|
||||
apiLogger.warn("JWT secret regenerated via API", {
|
||||
operation: "jwt_secret_regenerate_api",
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: "New JWT secret generated",
|
||||
warning: "All existing JWT tokens are now invalid - users must re-authenticate",
|
||||
});
|
||||
} catch (error) {
|
||||
apiLogger.error("Failed to regenerate JWT secret", error, {
|
||||
operation: "jwt_secret_regenerate_failed",
|
||||
});
|
||||
res.status(500).json({ error: "Failed to regenerate JWT secret" });
|
||||
}
|
||||
});
|
||||
|
||||
// Database migration and backup endpoints
|
||||
app.post("/database/export", async (req, res) => {
|
||||
try {
|
||||
@@ -689,10 +712,20 @@ async function initializeEncryption() {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Initialize JWT secret using the same encryption infrastructure
|
||||
const { EncryptionKeyManager } = await import("../utils/encryption-key-manager.js");
|
||||
const keyManager = EncryptionKeyManager.getInstance();
|
||||
await keyManager.getJWTSecret();
|
||||
|
||||
databaseLogger.success("JWT secret initialized successfully", {
|
||||
operation: "jwt_secret_init_complete",
|
||||
});
|
||||
} catch (error) {
|
||||
databaseLogger.error("Failed to initialize database encryption", error, {
|
||||
operation: "encryption_init_error",
|
||||
});
|
||||
throw error; // JWT secret is critical for API functionality
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user