✨ Fully rewrite relay
This commit is contained in:
parent
190e38dfc1
commit
20ffbd4c6d
47 changed files with 3489 additions and 128 deletions
220
src/utils/securityLogs.ts
Normal file
220
src/utils/securityLogs.ts
Normal file
|
@ -0,0 +1,220 @@
|
|||
import { log } from './logs.ts';
|
||||
|
||||
export enum SecurityEventType {
|
||||
// Authentication & Authorization
|
||||
CCN_ACCESS_DENIED = 'ccn_access_denied',
|
||||
CCN_ACTIVATION_ATTEMPT = 'ccn_activation_attempt',
|
||||
CCN_CREATION_ATTEMPT = 'ccn_creation_attempt',
|
||||
UNAUTHORIZED_WRITE_ATTEMPT = 'unauthorized_write_attempt',
|
||||
|
||||
// Connection Security
|
||||
NON_LOCALHOST_CONNECTION_BLOCKED = 'non_localhost_connection_blocked',
|
||||
SUSPICIOUS_HEADER_DETECTED = 'suspicious_header_detected',
|
||||
WEBSOCKET_CONNECTION_ESTABLISHED = 'websocket_connection_established',
|
||||
WEBSOCKET_CONNECTION_CLOSED = 'websocket_connection_closed',
|
||||
|
||||
// Cryptographic Operations
|
||||
DECRYPTION_FAILURE = 'decryption_failure',
|
||||
INVALID_SIGNATURE = 'invalid_signature',
|
||||
POW_VALIDATION_FAILURE = 'pow_validation_failure',
|
||||
ENCRYPTION_ERROR = 'encryption_error',
|
||||
|
||||
// Event Processing
|
||||
DUPLICATE_EVENT_BLOCKED = 'duplicate_event_blocked',
|
||||
MALFORMED_EVENT = 'malformed_event',
|
||||
CHUNKED_EVENT_RECEIVED = 'chunked_event_received',
|
||||
CHUNKED_EVENT_COMPLETED = 'chunked_event_completed',
|
||||
EVENT_QUEUED_FOR_TRANSMISSION = 'event_queued_for_transmission',
|
||||
|
||||
// Resource Usage & DoS Protection
|
||||
SUBSCRIPTION_LIMIT_EXCEEDED = 'subscription_limit_exceeded',
|
||||
MEMORY_USAGE_HIGH = 'memory_usage_high',
|
||||
LARGE_PAYLOAD_DETECTED = 'large_payload_detected',
|
||||
|
||||
// Database Security
|
||||
SQL_QUERY_EXECUTED = 'sql_query_executed',
|
||||
MIGRATION_EXECUTED = 'migration_executed',
|
||||
TRANSACTION_ROLLBACK = 'transaction_rollback',
|
||||
|
||||
// CCN Boundary Violations
|
||||
CCN_BOUNDARY_VIOLATION_ATTEMPT = 'ccn_boundary_violation_attempt',
|
||||
INVITE_VALIDATION_FAILURE = 'invite_validation_failure',
|
||||
INVITE_ALREADY_USED = 'invite_already_used',
|
||||
|
||||
// System Events
|
||||
SYSTEM_STARTUP = 'system_startup',
|
||||
SYSTEM_SHUTDOWN = 'system_shutdown',
|
||||
CONFIGURATION_LOADED = 'configuration_loaded',
|
||||
ERROR_THRESHOLD_EXCEEDED = 'error_threshold_exceeded',
|
||||
}
|
||||
|
||||
export enum SecuritySeverity {
|
||||
LOW = 'low',
|
||||
MEDIUM = 'medium',
|
||||
HIGH = 'high',
|
||||
CRITICAL = 'critical',
|
||||
}
|
||||
|
||||
export interface SecurityEventData {
|
||||
eventType: SecurityEventType;
|
||||
severity: SecuritySeverity;
|
||||
timestamp: string;
|
||||
source: string;
|
||||
details: Record<string, unknown>;
|
||||
userAgent?: string;
|
||||
remoteAddr?: string;
|
||||
ccnPubkey?: string;
|
||||
userId?: string;
|
||||
eventId?: string;
|
||||
subscriptionId?: string;
|
||||
risk_score?: number;
|
||||
}
|
||||
|
||||
class SecurityLogger {
|
||||
private readonly eventCounts = new Map<SecurityEventType, number>();
|
||||
private readonly lastEventTime = new Map<SecurityEventType, number>();
|
||||
|
||||
logSecurityEvent(data: Omit<SecurityEventData, 'timestamp'>): void {
|
||||
const eventData: SecurityEventData = {
|
||||
...data,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
this.updateEventTracking(data.eventType);
|
||||
|
||||
switch (data.severity) {
|
||||
case SecuritySeverity.CRITICAL:
|
||||
log.error(`SECURITY_CRITICAL: ${data.eventType}`, eventData);
|
||||
break;
|
||||
case SecuritySeverity.HIGH:
|
||||
log.error(`SECURITY_HIGH: ${data.eventType}`, eventData);
|
||||
break;
|
||||
case SecuritySeverity.MEDIUM:
|
||||
log.warn(`SECURITY_MEDIUM: ${data.eventType}`, eventData);
|
||||
break;
|
||||
case SecuritySeverity.LOW:
|
||||
log.info(`SECURITY_LOW: ${data.eventType}`, eventData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logAuthEvent(
|
||||
eventType: SecurityEventType,
|
||||
success: boolean,
|
||||
details: Record<string, unknown>,
|
||||
remoteAddr?: string,
|
||||
): void {
|
||||
this.logSecurityEvent({
|
||||
eventType,
|
||||
severity: success ? SecuritySeverity.LOW : SecuritySeverity.MEDIUM,
|
||||
source: 'authentication',
|
||||
details: { success, ...details },
|
||||
remoteAddr,
|
||||
});
|
||||
}
|
||||
|
||||
logCCNViolation(
|
||||
eventType: SecurityEventType,
|
||||
ccnPubkey: string,
|
||||
attemptedAction: string,
|
||||
details: Record<string, unknown>,
|
||||
): void {
|
||||
this.logSecurityEvent({
|
||||
eventType,
|
||||
severity: SecuritySeverity.HIGH,
|
||||
source: 'ccn_boundary',
|
||||
ccnPubkey,
|
||||
details: { attemptedAction, ...details },
|
||||
risk_score: 8.5,
|
||||
});
|
||||
}
|
||||
|
||||
logCryptoFailure(
|
||||
eventType: SecurityEventType,
|
||||
operation: string,
|
||||
details: Record<string, unknown>,
|
||||
): void {
|
||||
this.logSecurityEvent({
|
||||
eventType,
|
||||
severity: SecuritySeverity.MEDIUM,
|
||||
source: 'cryptography',
|
||||
details: { operation, ...details },
|
||||
});
|
||||
}
|
||||
|
||||
logDoSEvent(
|
||||
eventType: SecurityEventType,
|
||||
details: Record<string, unknown>,
|
||||
remoteAddr?: string,
|
||||
): void {
|
||||
this.logSecurityEvent({
|
||||
eventType,
|
||||
severity: SecuritySeverity.HIGH,
|
||||
source: 'dos_protection',
|
||||
details,
|
||||
remoteAddr,
|
||||
risk_score: 7.0,
|
||||
});
|
||||
}
|
||||
|
||||
logSystemEvent(
|
||||
eventType: SecurityEventType,
|
||||
details: Record<string, unknown>,
|
||||
): void {
|
||||
this.logSecurityEvent({
|
||||
eventType,
|
||||
severity: SecuritySeverity.LOW,
|
||||
source: 'system',
|
||||
details,
|
||||
});
|
||||
}
|
||||
|
||||
private updateEventTracking(eventType: SecurityEventType): void {
|
||||
const now = Date.now();
|
||||
const count = this.eventCounts.get(eventType) || 0;
|
||||
this.eventCounts.set(eventType, count + 1);
|
||||
this.lastEventTime.set(eventType, now);
|
||||
}
|
||||
}
|
||||
|
||||
export const securityLogger = new SecurityLogger();
|
||||
|
||||
export const logSecurityEvent = (data: Omit<SecurityEventData, 'timestamp'>) =>
|
||||
securityLogger.logSecurityEvent(data);
|
||||
|
||||
export const logAuthEvent = (
|
||||
eventType: SecurityEventType,
|
||||
success: boolean,
|
||||
details: Record<string, unknown>,
|
||||
remoteAddr?: string,
|
||||
) => securityLogger.logAuthEvent(eventType, success, details, remoteAddr);
|
||||
|
||||
export const logCCNViolation = (
|
||||
eventType: SecurityEventType,
|
||||
ccnPubkey: string,
|
||||
attemptedAction: string,
|
||||
details: Record<string, unknown>,
|
||||
) =>
|
||||
securityLogger.logCCNViolation(
|
||||
eventType,
|
||||
ccnPubkey,
|
||||
attemptedAction,
|
||||
details,
|
||||
);
|
||||
|
||||
export const logCryptoFailure = (
|
||||
eventType: SecurityEventType,
|
||||
operation: string,
|
||||
details: Record<string, unknown>,
|
||||
) => securityLogger.logCryptoFailure(eventType, operation, details);
|
||||
|
||||
export const logDoSEvent = (
|
||||
eventType: SecurityEventType,
|
||||
details: Record<string, unknown>,
|
||||
remoteAddr?: string,
|
||||
) => securityLogger.logDoSEvent(eventType, details, remoteAddr);
|
||||
|
||||
export const logSystemEvent = (
|
||||
eventType: SecurityEventType,
|
||||
details: Record<string, unknown>,
|
||||
) => securityLogger.logSystemEvent(eventType, details);
|
Loading…
Add table
Add a link
Reference in a new issue