UNPKG

@mitre-attack/attack-data-model

Version:

A TypeScript API for the MITRE ATT&CK data model

247 lines (244 loc) 10.1 kB
import { z } from 'zod/v4'; import { StixType } from './stix-type.js'; /** * Comprehensive ATT&CK ID configuration map. * This single source of truth defines all ATT&CK ID types, their patterns, messages, and STIX type mappings. * * To add a new ATT&CK ID type: * 1. Add an entry to this map with the pattern, message, example, and stixTypes * 2. That's it! All other functionality will automatically work. */ declare const attackIdConfig: { readonly tactic: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Tactic ID format (TA####)"; readonly example: "TA####"; readonly stixTypes: readonly ["x-mitre-tactic"]; }; readonly technique: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Technique ID format (T####)"; readonly example: "T####"; readonly stixTypes: readonly ["attack-pattern"]; }; readonly subtechnique: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Sub-technique ID format (T####.###)"; readonly example: "T####.###"; readonly stixTypes: readonly ["attack-pattern"]; }; readonly group: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Group ID format (G####)"; readonly example: "G####"; readonly stixTypes: readonly ["intrusion-set"]; }; readonly software: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Software ID format (S####)"; readonly example: "S####"; readonly stixTypes: readonly ["malware", "tool"]; }; readonly mitigation: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Mitigation ID format (M####)"; readonly example: "M####"; readonly stixTypes: readonly ["course-of-action"]; }; readonly asset: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Asset ID format (A####)"; readonly example: "A####"; readonly stixTypes: readonly ["x-mitre-asset"]; }; readonly 'data-source': { readonly pattern: RegExp; readonly message: "Must match ATT&CK Data Source ID format (DS####)"; readonly example: "DS####"; readonly stixTypes: readonly ["x-mitre-data-source"]; }; readonly campaign: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Campaign ID format (C####)"; readonly example: "C####"; readonly stixTypes: readonly ["campaign"]; }; readonly 'data-component': { readonly pattern: RegExp; readonly message: "Must match ATT&CK Data Component Source ID format (DC####)"; readonly example: "DC####"; readonly stixTypes: readonly ["x-mitre-data-component"]; }; readonly 'detection-strategy': { readonly pattern: RegExp; readonly message: "Must match ATT&CK Detection Strategy Source ID format (DET####)"; readonly example: "DET####"; readonly stixTypes: readonly ["x-mitre-detection-strategy"]; }; readonly analytic: { readonly pattern: RegExp; readonly message: "Must match ATT&CK Analytic Source ID format (AN####)"; readonly example: "AN####"; readonly stixTypes: readonly ["x-mitre-analytic"]; }; }; /** * Union type of all valid ATT&CK ID type keys. * * @example * ```typescript * const idType: AttackIdType = 'technique'; // Valid * const idType: AttackIdType = 'tactic'; // Valid * const idType: AttackIdType = 'invalid'; // Type error * ``` */ type AttackIdType = keyof typeof attackIdConfig; /** * Union type of all STIX types that have associated ATT&CK IDs. * * This extracts only the STIX types that appear in the attackIdConfig mapping, * excluding STIX types that don't have ATT&CK IDs (e.g., marking-definition, identity, etc.). * * @example * ```typescript * const stixType: StixTypesWithAttackIds = 'attack-pattern'; // Valid * const stixType: StixTypesWithAttackIds = 'x-mitre-tactic'; // Valid * const stixType: StixTypesWithAttackIds = 'marking-definition'; // Type error - no ATT&CK ID * ``` */ type StixTypesWithAttackIds = Extract<StixType, (typeof attackIdConfig)[AttackIdType]['stixTypes'][number]>; /** * Reverse mapping from STIX type to ATT&CK ID type. * * This allows looking up which ATT&CK ID format corresponds to a given STIX type. * Note that 'attack-pattern' defaults to 'technique', but subtechniques are handled * contextually where needed. * * @example * ```typescript * stixTypeToAttackIdMapping['x-mitre-tactic']; // 'tactic' * stixTypeToAttackIdMapping['malware']; // 'software' * stixTypeToAttackIdMapping['attack-pattern']; // 'technique' * ``` */ declare const stixTypeToAttackIdMapping: Record<StixTypesWithAttackIds, AttackIdType>; /** * Map of ATT&CK ID types to their respective RegEx patterns. * * Maps `AttackIdType` instead of `StixType` because not all STIX types have ATT&CK ID patterns. * For example, `marking-definition`, `identity`, `relationship`, `bundle`, and `collection` * do not have ATT&CK ID patterns. * * @example * ```typescript * attackIdPatterns.technique; // /^T\d{4}$/ * attackIdPatterns.tactic; // /^TA\d{4}$/ * attackIdPatterns.subtechnique; // /^T\d{4}\.\d{3}$/ * ``` */ declare const attackIdPatterns: Record<AttackIdType, RegExp>; /** * Map of ATT&CK ID types to their validation error messages. * * Used for providing helpful error messages when ATT&CK ID validation fails. * * @example * ```typescript * attackIdMessages.technique; // 'Must match ATT&CK Technique ID format (T####)' * attackIdMessages.group; // 'Must match ATT&CK Group ID format (G####)' * ``` */ declare const attackIdMessages: Record<AttackIdType, string>; /** * Map of ATT&CK ID types to their format examples. * * Provides example formats for documentation and error messages. * * @example * ```typescript * attackIdExamples.technique; // 'T####' * attackIdExamples.subtechnique; // 'T####.###' * attackIdExamples['data-source']; // 'DS####' * ``` */ declare const attackIdExamples: Record<AttackIdType, string>; /** * Gets the ATT&CK ID format example for a given STIX type. * * Provides special handling for 'attack-pattern' which can be either a technique * or a subtechnique, returning both possible formats. * * @param stixType - The STIX type to get the ATT&CK ID example for * @returns The format example string (e.g., 'T####' or 'T#### or T####.###') * * @example * ```typescript * getAttackIdExample('x-mitre-tactic'); // 'TA####' * getAttackIdExample('attack-pattern'); // 'T#### or T####.###' * getAttackIdExample('malware'); // 'S####' * ``` */ declare function getAttackIdExample(stixType: StixTypesWithAttackIds): string; /** * Creates a Zod schema for validating ATT&CK IDs based on STIX type. * * This factory function generates a Zod string schema that validates ATT&CK IDs * according to the format required for the given STIX type. Special handling is * provided for 'attack-pattern' which accepts both technique and subtechnique formats. * * @param stixType - The STIX type that determines which ATT&CK ID format to validate * @returns A Zod string schema configured for the appropriate ATT&CK ID format * * @example * ```typescript * const tacticIdSchema = createAttackIdSchema('x-mitre-tactic'); * tacticIdSchema.parse('TA0001'); // Valid - returns 'TA0001' * tacticIdSchema.parse('T0001'); // Invalid - throws error * * const techniqueIdSchema = createAttackIdSchema('attack-pattern'); * techniqueIdSchema.parse('T1234'); // Valid - technique format * techniqueIdSchema.parse('T1234.001'); // Valid - subtechnique format * techniqueIdSchema.parse('TA0001'); // Invalid - wrong format * ``` */ declare const createAttackIdSchema: (stixType: StixTypesWithAttackIds) => z.ZodString; /** * Creates a type-specific schema for validating old mobile ATT&CK IDs (`x_mitre_old_attack_id`). * * This factory function generates schemas that validate old mobile ATT&CK IDs based on * the STIX type. Software types (malware, tool) use MOB-S####, while mitigations * (course-of-action) use MOB-M####. * * @param stixType - The STIX type to create the schema for (malware, tool, or course-of-action) * @returns A Zod schema configured for the appropriate old ATT&CK ID format * * @example * ```typescript * const softwareOldIdSchema = createOldMitreAttackIdSchema('malware'); * softwareOldIdSchema.parse("MOB-S0012"); // Valid * softwareOldIdSchema.parse("MOB-M1008"); // Invalid - wrong prefix for software * * const mitigationOldIdSchema = createOldMitreAttackIdSchema('course-of-action'); * mitigationOldIdSchema.parse("MOB-M1008"); // Valid * ``` */ declare function createOldMitreAttackIdSchema(stixType: Extract<StixType, 'malware' | 'tool' | 'course-of-action'>): z.ZodString & z.ZodType<`MOB-M${number}` | `MOB-S${number}`, string, z.core.$ZodTypeInternals<`MOB-M${number}` | `MOB-S${number}`, string>>; /** * Generic schema for validating old mobile ATT&CK IDs (`x_mitre_old_attack_id`). * * Validates IDs in the format MOB-X#### where X is either 'M' or 'S', followed by * exactly four digits. For type-specific validation, use `createOldMitreAttackIdSchema()`. * * @example * ```typescript * xMitreOldAttackIdSchema.parse("MOB-M1008"); // Valid * xMitreOldAttackIdSchema.parse("MOB-S0012"); // Valid * xMitreOldAttackIdSchema.parse("MOB-T1234"); // Invalid - wrong prefix * ``` */ declare const xMitreOldAttackIdSchema: z.ZodString & z.ZodType<`MOB-M${number}` | `MOB-S${number}`, string, z.core.$ZodTypeInternals<`MOB-M${number}` | `MOB-S${number}`, string>>; /** * Type representing a validated old mobile ATT&CK ID. */ type XMitreOldAttackId = z.infer<typeof xMitreOldAttackIdSchema>; export { type AttackIdType, type StixTypesWithAttackIds, type XMitreOldAttackId, attackIdExamples, attackIdMessages, attackIdPatterns, createAttackIdSchema, createOldMitreAttackIdSchema, getAttackIdExample, stixTypeToAttackIdMapping, xMitreOldAttackIdSchema };