@mitre-attack/attack-data-model
Version:
A TypeScript API for the MITRE ATT&CK data model
83 lines (80 loc) • 3.18 kB
JavaScript
import {
createStixIdValidator,
stixIdentifierSchema
} from "./chunk-BX5HSTNG.js";
import {
attackIdPatterns,
stixTypeToAttackIdMapping
} from "./chunk-ZNZXHYQL.js";
// src/schemas/common/misc.ts
import { z } from "zod";
var externalReferenceSchema = z.object({
source_name: z.string({
required_error: "Source name is required.",
invalid_type_error: "Source name must be a string."
}),
description: z.string({ invalid_type_error: "Description must be a string." }).optional(),
url: z.string({ invalid_type_error: "URL must be a string." }).url({ message: "Invalid URL format. Please provide a valid URL." }).optional(),
external_id: z.string({ invalid_type_error: "External ID must be a string." }).optional()
});
var externalReferencesSchema = z.array(externalReferenceSchema).min(1, "At least one external reference is required when 'external_references' is defined.").describe("A list of external references which refers to non-STIX information.");
var createAttackExternalReferencesSchema = (stixType) => {
return z.array(externalReferenceSchema).min(1, "At least one external reference is required").refine((refs) => !!refs[0]?.external_id, {
message: "ATT&CK ID must be defined in the first external_references entry.",
path: [0, "external_id"]
}).refine(
(refs) => {
if (!refs[0]?.external_id) return true;
const format = stixTypeToAttackIdMapping[stixType];
return attackIdPatterns[format].test(refs[0].external_id);
},
{
message: `The first external_reference must match the ATT&CK ID format ${getFormatExample(stixType)}.`,
path: [0, "external_id"]
}
).describe("A list of external references with the first containing a valid ATT&CK ID");
};
function getFormatExample(stixType) {
switch (stixType) {
case "x-mitre-tactic":
return "TA####";
case "attack-pattern":
return "T#### or T####.###";
case "intrusion-set":
return "G####";
case "malware":
case "tool":
return "S####";
case "course-of-action":
return "M####";
case "x-mitre-data-source":
return "DS####";
case "x-mitre-asset":
return "A####";
case "campaign":
return "C####";
default:
return "";
}
}
var stixCreatedByRefSchema = createStixIdValidator("identity").describe(
"The created_by_ref property specifies the id property of the identity object that describes the entity that created this object. If this attribute is omitted, the source of this information is undefined. This may be used by object creators who wish to remain anonymous."
);
var granularMarkingSchema = z.object({
marking_ref: stixIdentifierSchema,
selectors: z.array(z.string())
});
var extensionSchema = z.object({
extension_type: z.string(),
extension_properties: z.record(z.unknown())
});
var extensionsSchema = z.record(z.union([extensionSchema, z.record(z.unknown())])).describe("Specifies any extensions of the object, as a dictionary.");
export {
externalReferenceSchema,
externalReferencesSchema,
createAttackExternalReferencesSchema,
stixCreatedByRefSchema,
granularMarkingSchema,
extensionSchema,
extensionsSchema
};