@mitre-attack/attack-data-model
Version:
A TypeScript API for the MITRE ATT&CK data model
55 lines (53 loc) • 1.84 kB
JavaScript
// src/schemas/common/attack-id.ts
import { z } from "zod";
var stixTypeToAttackIdMapping = {
"x-mitre-tactic": "tactic",
"attack-pattern": "technique",
// Note: subtechniques are also attack-patterns, but need separate handling
"intrusion-set": "group",
malware: "software",
tool: "software",
"course-of-action": "mitigation",
"x-mitre-asset": "asset",
"x-mitre-data-source": "data-source",
campaign: "campaign"
};
var attackIdPatterns = {
tactic: /^TA\d{4}$/,
technique: /^T\d{4}$/,
subtechnique: /^T\d{4}\.\d{3}$/,
group: /^G\d{4}$/,
software: /^S\d{4}$/,
mitigation: /^M\d{4}$/,
asset: /^A\d{4}$/,
"data-source": /^DS\d{4}$/,
campaign: /^C\d{4}$/
};
var attackIdMessages = {
tactic: "Must match ATT&CK Tactic ID format (TA####)",
technique: "Must match ATT&CK Technique ID format (T####)",
subtechnique: "Must match ATT&CK Sub-technique ID format (T####.###)",
group: "Must match ATT&CK Group ID format (G####)",
software: "Must match ATT&CK Software ID format (S####)",
mitigation: "Must match ATT&CK Mitigation ID format (M####)",
asset: "Must match ATT&CK Asset ID format (A####)",
"data-source": "Must match ATT&CK Data Source ID format (DS####)",
campaign: "Must match ATT&CK Campaign ID format (C####)"
};
var createAttackIdSchema = (stixType) => {
const format = stixTypeToAttackIdMapping[stixType];
if (stixType === "attack-pattern") {
return z.string().refine(
(id) => attackIdPatterns.technique.test(id) || attackIdPatterns.subtechnique.test(id),
() => ({
message: `Must match either ATT&CK Technique ID format (T####) or Sub-technique ID format (T####.###)`
})
);
}
return z.string().regex(attackIdPatterns[format], attackIdMessages[format]);
};
export {
stixTypeToAttackIdMapping,
attackIdPatterns,
createAttackIdSchema
};