@ahmedhegazee/nestjs-telescope
Version:
Advanced observability and monitoring solution for NestJS applications with ML-powered analytics, enterprise features, and production-ready scaling
548 lines (544 loc) • 23.4 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var SecurityAuditService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecurityAuditService = void 0;
const common_1 = require("@nestjs/common");
const rxjs_1 = require("rxjs");
let SecurityAuditService = SecurityAuditService_1 = class SecurityAuditService {
constructor() {
this.logger = new common_1.Logger(SecurityAuditService_1.name);
this.vulnerabilities = new Map();
this.securitySubject = new rxjs_1.Subject();
this.vulnerabilitySubject = new rxjs_1.Subject();
this.securityConfig = {
auditInterval: 24 * 60 * 60 * 1000,
maxFailedAttempts: 5,
sessionTimeout: 30 * 60 * 1000,
passwordPolicy: {
minLength: 12,
requireUppercase: true,
requireLowercase: true,
requireNumbers: true,
requireSpecialChars: true,
maxAge: 90 * 24 * 60 * 60 * 1000,
},
encryption: {
algorithm: "aes-256-gcm",
keyRotationInterval: 30 * 24 * 60 * 60 * 1000,
},
logging: {
securityEvents: true,
dataAccess: true,
configurationChanges: true,
retentionDays: 365,
},
};
this.dataClassificationMatrix = new Map([
[
"user_personal_data",
{
level: "confidential",
description: "Personal identifiable information",
encryptionRequired: true,
retentionPolicy: "7 years",
accessControls: ["role-based", "audit-logging", "encryption-at-rest"],
},
],
[
"system_configuration",
{
level: "internal",
description: "System configuration and settings",
encryptionRequired: true,
retentionPolicy: "indefinite",
accessControls: ["admin-only", "change-tracking"],
},
],
[
"performance_metrics",
{
level: "internal",
description: "System performance and monitoring data",
encryptionRequired: false,
retentionPolicy: "1 year",
accessControls: ["read-only", "aggregated-access"],
},
],
[
"security_logs",
{
level: "restricted",
description: "Security audit logs and events",
encryptionRequired: true,
retentionPolicy: "7 years",
accessControls: ["security-team-only", "immutable-logs"],
},
],
]);
this.startSecurityMonitoring();
}
startSecurityMonitoring() {
(0, rxjs_1.interval)(this.securityConfig.auditInterval).subscribe(() => {
this.performSecurityAudit();
});
(0, rxjs_1.interval)(5 * 60 * 1000).subscribe(() => {
this.checkForNewVulnerabilities();
});
}
async performSecurityAudit() {
this.logger.log("Starting comprehensive security audit...");
const vulnerabilities = [];
const authVulnerabilities = await this.auditAuthenticationAndAuthorization();
vulnerabilities.push(...authVulnerabilities);
const dataVulnerabilities = await this.auditDataProtection();
vulnerabilities.push(...dataVulnerabilities);
const inputVulnerabilities = await this.auditInputValidation();
vulnerabilities.push(...inputVulnerabilities);
const encryptionVulnerabilities = await this.auditEncryption();
vulnerabilities.push(...encryptionVulnerabilities);
const loggingVulnerabilities = await this.auditLoggingAndMonitoring();
vulnerabilities.push(...loggingVulnerabilities);
const configVulnerabilities = await this.auditConfigurationSecurity();
vulnerabilities.push(...configVulnerabilities);
const overallScore = this.calculateSecurityScore(vulnerabilities);
const riskLevel = this.determineRiskLevel(overallScore);
const complianceStatus = this.checkComplianceStatus(vulnerabilities);
const recommendations = this.generateSecurityRecommendations(vulnerabilities);
const auditResult = {
timestamp: new Date(),
overallScore,
riskLevel,
vulnerabilities,
complianceStatus,
recommendations,
nextAuditDate: new Date(Date.now() + this.securityConfig.auditInterval),
};
vulnerabilities.forEach((vuln) => {
this.vulnerabilities.set(vuln.id, vuln);
});
this.securitySubject.next(auditResult);
this.vulnerabilitySubject.next(Array.from(this.vulnerabilities.values()));
this.logger.log(`Security audit completed. Score: ${overallScore}/100, Risk Level: ${riskLevel}`);
return auditResult;
}
async auditAuthenticationAndAuthorization() {
const vulnerabilities = [];
if (!this.securityConfig.passwordPolicy.requireSpecialChars) {
vulnerabilities.push({
id: "AUTH-001",
severity: "medium",
category: "authentication",
title: "Weak Password Policy",
description: "Password policy does not require special characters",
impact: "Increased risk of password-based attacks",
recommendation: "Enforce special character requirement in password policy",
detectedAt: new Date(),
status: "open",
});
}
if (this.securityConfig.sessionTimeout > 60 * 60 * 1000) {
vulnerabilities.push({
id: "AUTH-002",
severity: "medium",
category: "authentication",
title: "Long Session Timeout",
description: "Session timeout is configured for more than 1 hour",
impact: "Increased risk of session hijacking",
recommendation: "Reduce session timeout to 30 minutes or less",
detectedAt: new Date(),
status: "open",
});
}
vulnerabilities.push({
id: "AUTH-003",
severity: "high",
category: "authorization",
title: "Missing Role-Based Access Control",
description: "System lacks comprehensive role-based access control",
impact: "Unauthorized access to sensitive data and functions",
recommendation: "Implement comprehensive RBAC with least privilege principle",
detectedAt: new Date(),
status: "open",
});
return vulnerabilities;
}
async auditDataProtection() {
const vulnerabilities = [];
vulnerabilities.push({
id: "DATA-001",
severity: "critical",
category: "data-protection",
title: "Unencrypted Sensitive Data",
description: "Sensitive data is stored without encryption",
impact: "Data breach risk and compliance violations",
recommendation: "Implement encryption at rest for all sensitive data",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "DATA-002",
severity: "high",
category: "data-protection",
title: "Missing Data Classification",
description: "System lacks proper data classification framework",
impact: "Inappropriate handling of sensitive data",
recommendation: "Implement data classification matrix and handling procedures",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "DATA-003",
severity: "medium",
category: "data-protection",
title: "Inadequate Data Retention Policies",
description: "Data retention policies are not properly defined or enforced",
impact: "Compliance violations and unnecessary data exposure",
recommendation: "Define and implement comprehensive data retention policies",
detectedAt: new Date(),
status: "open",
});
return vulnerabilities;
}
async auditInputValidation() {
const vulnerabilities = [];
vulnerabilities.push({
id: "INPUT-001",
severity: "critical",
category: "input-validation",
title: "Potential SQL Injection Vulnerabilities",
description: "System may be vulnerable to SQL injection attacks",
impact: "Unauthorized data access and manipulation",
recommendation: "Use parameterized queries and input validation",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "INPUT-002",
severity: "high",
category: "input-validation",
title: "Cross-Site Scripting (XSS) Vulnerabilities",
description: "System may be vulnerable to XSS attacks",
impact: "Client-side code execution and session hijacking",
recommendation: "Implement proper input sanitization and output encoding",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "INPUT-003",
severity: "critical",
category: "input-validation",
title: "Command Injection Vulnerabilities",
description: "System may be vulnerable to command injection attacks",
impact: "Remote code execution and system compromise",
recommendation: "Avoid command execution with user input, use safe APIs",
detectedAt: new Date(),
status: "open",
});
return vulnerabilities;
}
async auditEncryption() {
const vulnerabilities = [];
if (this.securityConfig.encryption.algorithm !== "aes-256-gcm") {
vulnerabilities.push({
id: "CRYPTO-001",
severity: "high",
category: "encryption",
title: "Weak Encryption Algorithm",
description: "System uses weak or deprecated encryption algorithms",
impact: "Data confidentiality compromise",
recommendation: "Use AES-256-GCM or stronger encryption algorithms",
detectedAt: new Date(),
status: "open",
});
}
vulnerabilities.push({
id: "CRYPTO-002",
severity: "medium",
category: "encryption",
title: "Missing Key Rotation Policy",
description: "Encryption keys are not rotated regularly",
impact: "Increased risk of key compromise",
recommendation: "Implement automatic key rotation every 30 days",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "CRYPTO-003",
severity: "critical",
category: "encryption",
title: "Insecure Key Storage",
description: "Encryption keys may be stored insecurely",
impact: "Complete encryption bypass",
recommendation: "Use hardware security modules (HSM) or secure key management",
detectedAt: new Date(),
status: "open",
});
return vulnerabilities;
}
async auditLoggingAndMonitoring() {
const vulnerabilities = [];
if (!this.securityConfig.logging.securityEvents) {
vulnerabilities.push({
id: "LOGGING-001",
severity: "high",
category: "logging",
title: "Insufficient Security Logging",
description: "Security events are not properly logged",
impact: "Inability to detect and respond to security incidents",
recommendation: "Implement comprehensive security event logging",
detectedAt: new Date(),
status: "open",
});
}
if (this.securityConfig.logging.retentionDays < 365) {
vulnerabilities.push({
id: "LOGGING-002",
severity: "medium",
category: "logging",
title: "Inadequate Log Retention",
description: "Log retention period is less than 1 year",
impact: "Compliance violations and loss of forensic data",
recommendation: "Extend log retention to at least 1 year",
detectedAt: new Date(),
status: "open",
});
}
vulnerabilities.push({
id: "LOGGING-003",
severity: "high",
category: "logging",
title: "Log Integrity Not Protected",
description: "Log files are not protected against tampering",
impact: "Log manipulation and evidence destruction",
recommendation: "Implement log integrity protection and write-once storage",
detectedAt: new Date(),
status: "open",
});
return vulnerabilities;
}
async auditConfigurationSecurity() {
const vulnerabilities = [];
vulnerabilities.push({
id: "CONFIG-001",
severity: "critical",
category: "authentication",
title: "Default Credentials in Use",
description: "System may be using default or hardcoded credentials",
impact: "Unauthorized access and system compromise",
recommendation: "Change all default credentials and use secure credential management",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "CONFIG-002",
severity: "high",
category: "data-protection",
title: "Insecure Configuration Settings",
description: "System configuration may have security weaknesses",
impact: "Various security vulnerabilities depending on configuration",
recommendation: "Review and harden all configuration settings",
detectedAt: new Date(),
status: "open",
});
vulnerabilities.push({
id: "CONFIG-003",
severity: "medium",
category: "data-protection",
title: "Missing Security Headers",
description: "Web application lacks important security headers",
impact: "Increased vulnerability to various web attacks",
recommendation: "Implement security headers (CSP, HSTS, X-Frame-Options, etc.)",
detectedAt: new Date(),
status: "open",
});
return vulnerabilities;
}
calculateSecurityScore(vulnerabilities) {
let score = 100;
vulnerabilities.forEach((vuln) => {
switch (vuln.severity) {
case "critical":
score -= 20;
break;
case "high":
score -= 10;
break;
case "medium":
score -= 5;
break;
case "low":
score -= 2;
break;
}
});
return Math.max(0, score);
}
determineRiskLevel(score) {
if (score >= 80)
return "low";
if (score >= 60)
return "medium";
if (score >= 40)
return "high";
return "critical";
}
checkComplianceStatus(vulnerabilities) {
const criticalVulns = vulnerabilities.filter((v) => v.severity === "critical");
const highVulns = vulnerabilities.filter((v) => v.severity === "high");
return {
gdpr: criticalVulns.length === 0 && highVulns.length <= 2,
sox: criticalVulns.length === 0 && highVulns.length <= 1,
hipaa: criticalVulns.length === 0 && highVulns.length === 0,
pci: criticalVulns.length === 0 && highVulns.length === 0,
};
}
generateSecurityRecommendations(vulnerabilities) {
const recommendations = [];
const criticalVulns = vulnerabilities.filter((v) => v.severity === "critical");
if (criticalVulns.length > 0) {
recommendations.push("URGENT: Address all critical vulnerabilities immediately");
}
if (vulnerabilities.some((v) => v.category === "authentication")) {
recommendations.push("Implement multi-factor authentication (MFA)");
}
if (vulnerabilities.some((v) => v.category === "encryption")) {
recommendations.push("Upgrade encryption standards to AES-256-GCM");
}
if (vulnerabilities.some((v) => v.category === "data-protection")) {
recommendations.push("Implement data classification and encryption at rest");
}
if (vulnerabilities.some((v) => v.category === "input-validation")) {
recommendations.push("Implement comprehensive input validation and sanitization");
}
if (vulnerabilities.some((v) => v.category === "logging")) {
recommendations.push("Enhance security logging and monitoring capabilities");
}
recommendations.push("Conduct regular security training for development team");
recommendations.push("Implement automated security testing in CI/CD pipeline");
recommendations.push("Establish incident response procedures");
return recommendations;
}
async checkForNewVulnerabilities() {
this.logger.debug("Checking for new vulnerabilities...");
}
getSecurityAuditStream() {
return this.securitySubject.asObservable();
}
getVulnerabilitiesStream() {
return this.vulnerabilitySubject.asObservable();
}
getCurrentVulnerabilities() {
return Array.from(this.vulnerabilities.values());
}
getSecurityMetrics() {
const vulnerabilities = this.getCurrentVulnerabilities();
const resolvedVulns = vulnerabilities.filter((v) => v.status === "resolved");
const avgResolutionTime = resolvedVulns.length > 0
? resolvedVulns.reduce((sum, v) => {
const resolutionTime = new Date().getTime() - v.detectedAt.getTime();
return sum + resolutionTime;
}, 0) /
resolvedVulns.length /
(1000 * 60 * 60)
: 0;
return {
totalVulnerabilities: vulnerabilities.length,
criticalVulnerabilities: vulnerabilities.filter((v) => v.severity === "critical").length,
highVulnerabilities: vulnerabilities.filter((v) => v.severity === "high")
.length,
mediumVulnerabilities: vulnerabilities.filter((v) => v.severity === "medium").length,
lowVulnerabilities: vulnerabilities.filter((v) => v.severity === "low")
.length,
resolvedVulnerabilities: resolvedVulns.length,
averageResolutionTime: avgResolutionTime,
securityScore: this.calculateSecurityScore(vulnerabilities),
lastAuditDate: new Date(),
};
}
updateVulnerabilityStatus(vulnerabilityId, status) {
const vulnerability = this.vulnerabilities.get(vulnerabilityId);
if (vulnerability) {
vulnerability.status = status;
this.vulnerabilities.set(vulnerabilityId, vulnerability);
this.vulnerabilitySubject.next(Array.from(this.vulnerabilities.values()));
return true;
}
return false;
}
getDataClassification(dataType) {
return this.dataClassificationMatrix.get(dataType);
}
validateSecurityConfiguration() {
const requiredConfigs = [
"passwordPolicy.minLength",
"passwordPolicy.requireUppercase",
"passwordPolicy.requireLowercase",
"passwordPolicy.requireNumbers",
"passwordPolicy.requireSpecialChars",
"encryption.algorithm",
"sessionTimeout",
];
return true;
}
generateSecurityReport() {
const metrics = this.getSecurityMetrics();
const vulnerabilities = this.getCurrentVulnerabilities();
let report = `
# Security Audit Report
Generated: ${new Date().toISOString()}
## Executive Summary
- Overall Security Score: ${metrics.securityScore}/100
- Total Vulnerabilities: ${metrics.totalVulnerabilities}
- Critical Vulnerabilities: ${metrics.criticalVulnerabilities}
- High Vulnerabilities: ${metrics.highVulnerabilities}
## Vulnerability Breakdown
- Critical: ${metrics.criticalVulnerabilities}
- High: ${metrics.highVulnerabilities}
- Medium: ${metrics.mediumVulnerabilities}
- Low: ${metrics.lowVulnerabilities}
- Resolved: ${metrics.resolvedVulnerabilities}
## Compliance Status
- GDPR: ${this.checkComplianceStatus(vulnerabilities).gdpr
? "✓ Compliant"
: "✗ Non-compliant"}
- SOX: ${this.checkComplianceStatus(vulnerabilities).sox
? "✓ Compliant"
: "✗ Non-compliant"}
- HIPAA: ${this.checkComplianceStatus(vulnerabilities).hipaa
? "✓ Compliant"
: "✗ Non-compliant"}
- PCI: ${this.checkComplianceStatus(vulnerabilities).pci
? "✓ Compliant"
: "✗ Non-compliant"}
## Detailed Vulnerabilities
`;
vulnerabilities.forEach((vuln) => {
report += `
### ${vuln.title} (${vuln.id})
- **Severity**: ${vuln.severity.toUpperCase()}
- **Category**: ${vuln.category}
- **Status**: ${vuln.status}
- **Description**: ${vuln.description}
- **Impact**: ${vuln.impact}
- **Recommendation**: ${vuln.recommendation}
- **Detected**: ${vuln.detectedAt.toISOString()}
`;
});
return report;
}
};
exports.SecurityAuditService = SecurityAuditService;
exports.SecurityAuditService = SecurityAuditService = SecurityAuditService_1 = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [])
], SecurityAuditService);
//# sourceMappingURL=security-audit.service.js.map