88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { AnalysisEngine } from '../analysis/index.js';
|
|
import type { Report } from '../types/index.js';
|
|
import { KillChainPhase } from '../types/index.js';
|
|
|
|
function makeReport(): Report {
|
|
return {
|
|
id: 'report-1',
|
|
missionId: 'mission-1',
|
|
type: 'full_report',
|
|
generatedAt: 123,
|
|
summary: {
|
|
overview: 'Summary includes Bearer summaryabcdefghijklmnop',
|
|
riskRating: 'critical',
|
|
criticalFindings: 1,
|
|
highFindings: 0,
|
|
mediumFindings: 0,
|
|
lowFindings: 0,
|
|
infoFindings: 0,
|
|
successfulExploits: 1,
|
|
credentialsHarvested: 1,
|
|
systemsCompromised: 1,
|
|
},
|
|
findings: [
|
|
{
|
|
id: 'finding-1',
|
|
title: 'Leaked token',
|
|
description: 'Captured Anthropic key sk-ant-api03-ABCDEFGHIJKLMNOP in config',
|
|
severity: 'critical',
|
|
targetId: 'target-1',
|
|
operatorId: 'operator-1',
|
|
phase: KillChainPhase.EXPLOIT,
|
|
evidence: [
|
|
{
|
|
type: 'output',
|
|
content: 'curl -H "Authorization: Bearer evidenceabcdefghijklmnop" https://svc.local',
|
|
timestamp: 123,
|
|
},
|
|
],
|
|
remediation: 'Rotate token=rawsecretvalue123456 immediately',
|
|
discoveredAt: 123,
|
|
},
|
|
],
|
|
attackPaths: [
|
|
{
|
|
id: 'path-1',
|
|
name: 'Use https://admin:hunter2@example.test/login',
|
|
description: 'Pivot with Bearer attackpathabcdefghijklmnop',
|
|
steps: ['Replay sk-ant-api03-QRSTUVWXABCDEFGHIJKLMNOP against API'],
|
|
findings: ['finding-1'],
|
|
impactLevel: 'critical',
|
|
},
|
|
],
|
|
recommendations: [
|
|
{
|
|
id: 'rec-1',
|
|
findingId: 'finding-1',
|
|
priority: 'immediate',
|
|
title: 'Remove API key',
|
|
description: 'Delete api_key=anotherrawsecretvalue from docs',
|
|
effort: 'low',
|
|
impact: 'high',
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
describe('AnalysisEngine report redaction', () => {
|
|
it('redacts secrets before exporting Markdown reports', () => {
|
|
const engine = Object.create(AnalysisEngine.prototype) as AnalysisEngine;
|
|
const markdown = engine.exportToMarkdown(makeReport());
|
|
|
|
for (const raw of [
|
|
'sk-ant-api03-ABCDEFGHIJKLMNOP',
|
|
'Bearer summaryabcdefghijklmnop',
|
|
'Bearer evidenceabcdefghijklmnop',
|
|
'rawsecretvalue123456',
|
|
'hunter2',
|
|
'attackpathabcdefghijklmnop',
|
|
'sk-ant-api03-QRSTUVWXABCDEFGHIJKLMNOP',
|
|
'anotherrawsecretvalue',
|
|
]) {
|
|
expect(markdown).not.toContain(raw);
|
|
}
|
|
expect(markdown).toContain('[redacted]');
|
|
});
|
|
});
|