trojanhorse-js
Version:
A comprehensive JavaScript library for fetching, managing, and analyzing global threat intelligence from multiple open-source feeds and security news sources. Unlike its mythological namesake, this Trojan protects your digital fortress.
259 lines (233 loc) • 7.79 kB
text/typescript
/**
* Threat Correlation Engine
*
* Advanced correlation system that combines threat intelligence from multiple feeds
* - Cross-feed validation and confidence scoring
* - Temporal analysis and pattern detection
* - False positive reduction through consensus
* - Threat enrichment and contextualization
*/
import { ThreatIndicator } from '../types';
// Correlation interfaces
// interface CorrelationResult {
// indicator: EnrichedThreatIndicator;
// sources: string[];
// correlationScore: number;
// consensusLevel: 'weak' | 'moderate' | 'strong' | 'consensus';
// riskScore: number;
// correlatedData: CorrelatedThreatData;
// }
// interface EnrichedThreatIndicator extends ThreatIndicator {
// correlationScore: number;
// consensusLevel: 'weak' | 'moderate' | 'strong' | 'consensus';
// riskScore: number;
// sourceFeedbacks: SourceFeedback[];
// temporalAnalysis: TemporalAnalysis;
// geoAnalysis?: GeoAnalysis;
// patterns: ThreatPattern[];
// }
// interface SourceFeedback {
// source: string;
// confidence: number;
// severity: 'low' | 'medium' | 'high' | 'critical';
// lastSeen: Date;
// reportCount?: number;
// categories: string[];
// agreement: number; // 0-1 score of agreement with other sources
// }
// interface TemporalAnalysis {
// firstSeen: Date;
// lastSeen: Date;
// activityPeriod: number; // days
// recentActivity: boolean;
// activityTrend: 'increasing' | 'decreasing' | 'stable' | 'sporadic';
// peakActivity?: Date;
// }
// interface GeoAnalysis {
// countries: string[];
// primaryCountry: string;
// suspiciousGeoPatterns: boolean;
// geoRiskScore: number;
// }
// interface ThreatPattern {
// type: 'behavioral' | 'temporal' | 'network' | 'categorical';
// pattern: string;
// confidence: number;
// evidenceSources: string[];
// }
interface CorrelatedThreatData {
relatedIndicators: ThreatIndicator[];
crossReferences: CrossReference[];
enrichmentData: EnrichmentData;
riskFactors: RiskFactor[];
patterns?: string[];
// Add properties needed by the code
correlationScore?: number;
consensusLevel?: 'weak' | 'moderate' | 'strong' | 'consensus';
riskScore?: number;
sources?: string[];
indicators?: ThreatIndicator[]; // For backward compatibility
}
interface CrossReference {
source: string;
referenceType: 'similar_behavior' | 'same_campaign' | 'related_infrastructure';
relatedValue: string;
confidence: number;
}
interface EnrichmentData {
asn?: {
number: number;
name: string;
country: string;
};
geolocation?: {
country: string;
city: string;
latitude?: number;
longitude?: number;
};
dns?: {
domain: string;
reverseDns: string[];
};
reputation?: {
overall: number;
categories: string[];
};
}
interface RiskFactor {
factor: string;
impact: 'low' | 'medium' | 'high' | 'critical';
description: string;
evidence: string[];
}
interface CorrelationConfig {
minimumSources: number;
consensusThreshold: number;
temporalWindowDays: number;
confidenceWeighting: Record<string, number>;
enableGeolocationAnalysis: boolean;
enablePatternDetection: boolean;
riskScoreWeights: {
consensus: number;
recency: number;
severity: number;
sourceReliability: number;
};
}
export class ThreatCorrelationEngine {
private config: CorrelationConfig;
// private sourceReliability: Map<string, number>;
// private knownPatterns: Map<string, ThreatPattern[]>;
// private correlationCache: Map<string, CorrelatedThreatData>;
constructor(config: Partial<CorrelationConfig> = {}) {
// Validate configuration
if (config.minimumSources !== undefined && config.minimumSources < 1) {
throw new Error('Invalid configuration: minimumSources must be at least 1');
}
if (config.consensusThreshold !== undefined && (config.consensusThreshold < 0 || config.consensusThreshold > 1)) {
throw new Error('Invalid configuration: consensusThreshold must be between 0 and 1');
}
this.config = {
minimumSources: 2,
consensusThreshold: 0.5,
temporalWindowDays: 7,
confidenceWeighting: {},
enableGeolocationAnalysis: false,
enablePatternDetection: true,
riskScoreWeights: {
consensus: 0.4,
recency: 0.3,
severity: 0.3,
sourceReliability: 0.2
},
...config
};
// this.correlationCache = new Map();
// this.sourceReliability = new Map();
// this.knownPatterns = new Map();
}
/**
* Main correlation method - simplified for Option A conservative approach
*/
public async correlate(indicators: ThreatIndicator[]): Promise<CorrelatedThreatData> {
if (indicators.length === 0) {
return {
relatedIndicators: [],
crossReferences: [],
enrichmentData: { reputation: { overall: 0, categories: [] } },
riskFactors: [],
patterns: [],
correlationScore: 0,
consensusLevel: 'weak',
riskScore: 0,
sources: [],
indicators: []
};
}
// Basic implementation for compatibility
const sources = [...new Set(indicators.map(i => i.source))];
const correlationScore = Math.min(indicators.length / this.config.minimumSources, 1);
const consensusLevel = correlationScore > 0.7 ? 'strong' : correlationScore > 0.4 ? 'moderate' : 'weak';
const riskScore = indicators.reduce((sum, i) => sum + i.confidence, 0) / indicators.length;
return {
relatedIndicators: indicators,
crossReferences: [],
enrichmentData: { reputation: { overall: riskScore * 100, categories: [] } },
riskFactors: [],
patterns: [],
correlationScore,
consensusLevel,
riskScore,
sources,
indicators // For backward compatibility
};
}
/**
* Export results in various formats
*/
public exportResult(result: CorrelatedThreatData, format: 'json' | 'stix' | 'csv' = 'json'): string {
switch (format) {
case 'json':
return JSON.stringify({ ...result, timestamp: new Date().toISOString() }, null, 2);
case 'stix': {
const stixObject = {
type: 'bundle',
id: `bundle--${Date.now()}`,
spec_version: '2.1',
objects: [{
type: 'indicator',
id: `indicator--${Date.now()}`,
created: new Date().toISOString(),
modified: new Date().toISOString(),
pattern: result.relatedIndicators?.[0]?.value || 'unknown',
labels: ['malicious-activity'],
confidence: Math.round((result.correlationScore || 0) * 100)
}]
};
return JSON.stringify(stixObject, null, 2);
}
case 'csv': {
const headers = 'type,value,confidence,sources,risk_score\n';
const rows = (result.relatedIndicators || []).map((indicator: any) =>
`${indicator.type},${indicator.value},${indicator.confidence},"${(result.sources || []).join(';')}",${result.riskScore || 0}`
).join('\n');
return headers + rows;
}
default:
throw new Error(`Unsupported export format: ${format}`);
}
}
/**
* Add integration - stub implementation
*/
public addIntegration(_name: string, _integration: any): void {
// Stub implementation for compatibility
}
/**
* Share result - stub implementation
*/
public async shareResult(_result: CorrelatedThreatData, _platform: string): Promise<void> {
// Stub implementation for compatibility
}
}