feat(rt-import): require base64 evidence images per technique

Each technique in the RT import JSON now requires at least one evidence
image (PNG/JPG/GIF/WebP/BMP, max 10 MB decoded) embedded as base64.

Backend:
- RTEvidenceEntry model: filename, data (base64), caption (optional)
- RTTechniqueEntry.evidence is now required
- Pre-validation raises 422 if any technique is missing evidence
- After test creation, images are decoded and stored in MinIO as
  Evidence records (team=red) linked to the test

Frontend:
- RTEvidenceEntry type added to api/tests.ts
- parseJson() validates evidence presence and structure per technique
- Preview table shows base64 thumbnails (up to 3 + overflow count)
- Format reference updated: evidence fields moved to Required section
- Import result shows total evidence images attached
This commit is contained in:
kitos
2026-06-05 12:57:22 +02:00
parent f4289249b8
commit 5f54396cb6
3 changed files with 157 additions and 3 deletions
+8 -1
View File
@@ -284,12 +284,19 @@ export interface TempoSyncResult {
// ── RT Import ──────────────────────────────────────────────────────
export interface RTEvidenceEntry {
filename: string; // e.g. "screenshot_edr.png"
data: string; // base64-encoded image (PNG / JPG / GIF / WebP / BMP)
caption?: string; // optional description
}
export interface RTTechniqueEntry {
mitre_id: string;
result: "detected" | "not_detected" | "partially_detected";
attack_success: boolean;
platform?: string;
notes?: string;
evidence: RTEvidenceEntry[]; // required — at least 1 image
}
export interface RTImportPayload {
@@ -303,7 +310,7 @@ export interface RTImportPayload {
export interface RTImportResult {
created: number;
skipped: number;
items: { mitre_id: string; test_name: string; result: string; attack_success: boolean }[];
items: { mitre_id: string; test_name: string; result: string; attack_success: boolean; evidence_attached: number }[];
warnings: { mitre_id: string; reason: string }[];
engagement: string;
}