@mitre-attack/attack-data-model
Version:
A TypeScript API for the MITRE ATT&CK data model
219 lines (212 loc) • 8.53 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/schemas/common/property-schemas/stix-granular-marking.ts
var stix_granular_marking_exports = {};
__export(stix_granular_marking_exports, {
granularMarkingSchema: () => granularMarkingSchema
});
module.exports = __toCommonJS(stix_granular_marking_exports);
var import_zod2 = require("zod");
// src/schemas/common/property-schemas/generics.ts
var import_zod = require("zod");
var nonEmptyRequiredString = import_zod.z.string().trim().min(1, { error: "At least one character is required. Whitespace is not permissible." });
var emptyStixListErrorMessage = "Empty lists are prohibited in STIX and MUST NOT be used as a substitute for omitting the property if it is optional. The list MUST be present and MUST have at least one value.";
var stixListOfString = import_zod.z.array(nonEmptyRequiredString).min(1, { error: emptyStixListErrorMessage });
// src/schemas/common/property-schemas/stix-id.ts
var import_v42 = require("zod/v4");
// src/schemas/common/property-schemas/stix-type.ts
var import_v4 = require("zod/v4");
var stixTypeToTypeName = {
"attack-pattern": "Technique",
bundle: "StixBundle",
campaign: "Campaign",
"course-of-action": "Mitigation",
"extension-definition": null,
identity: "Identity",
"intrusion-set": "Group",
malware: "Malware",
tool: "Tool",
"marking-definition": "MarkingDefinition",
"x-mitre-analytic": "Analytic",
"x-mitre-data-component": "DataComponent",
"x-mitre-detection-strategy": "DetectionStrategy",
"x-mitre-data-source": "DataSource",
"x-mitre-tactic": "Tactic",
"x-mitre-asset": "Asset",
"x-mitre-matrix": "Matrix",
"x-mitre-collection": "Collection",
relationship: "Relationship",
file: "",
// not used in ATT&CK but used in sample_refs for Malware
artifact: ""
// not used in ATT&CK but used in sample_refs for Malware
// 'observed-data': 'ObservedData', // not used in ATT&CK
// 'report': 'Report', // not used in ATT&CK
// 'threat-actor': 'ThreatActor', // not used in ATT&CK
// 'vulnerability': 'Vulnerability', // not used in ATT&CK
};
var supportedStixTypes = [
"attack-pattern",
"bundle",
"campaign",
"course-of-action",
"extension-definition",
"identity",
"intrusion-set",
"malware",
"tool",
"marking-definition",
"x-mitre-analytic",
"x-mitre-data-component",
"x-mitre-detection-strategy",
"x-mitre-tactic",
"x-mitre-asset",
"x-mitre-data-source",
"x-mitre-matrix",
"x-mitre-collection",
"relationship",
"file",
// not used in ATT&CK but used in sample_refs for Malware
"artifact"
// not used in ATT&CK but used in sample_refs for Malware
// "indicator", // not used in ATT&CK
// "observed-data", // not used in ATT&CK
// "report", // not used in ATT&CK
// "threat-actor", // not used in ATT&CK
// "vulnerability", // not used in ATT&CK
];
var stixTypeSchema = import_v4.z.enum(supportedStixTypes, {
error: (issue) => {
if (issue.code === "invalid_value") {
const received = typeof issue.input === "string" ? issue.input : String(issue.input);
return `Invalid STIX type '${received}'. Expected one of the supported STIX types.`;
}
return void 0;
}
}).meta({
description: "The type property identifies the type of STIX Object (SDO, Relationship Object, etc). The value of the type field MUST be one of the types defined by a STIX Object (e.g., indicator)."
});
// src/schemas/common/property-schemas/stix-id.ts
var stixIdentifierSchema = import_v42.z.string().refine((val) => val.includes("--") && val.split("--").length === 2, {
error: (issue) => ({
code: "custom",
message: "Invalid STIX Identifier: must comply with format 'type--UUIDv4'",
input: issue.input,
path: []
})
}).refine(
(val) => {
const [type] = val.split("--");
return stixTypeSchema.safeParse(type).success;
},
{
error: (issue) => {
const val = issue.input;
const [type] = val.split("--");
const typeName = type in stixTypeToTypeName ? stixTypeToTypeName[type] : "STIX";
return {
code: "custom",
message: `Invalid STIX Identifier for ${typeName} object: contains invalid STIX type '${type}'`,
input: issue.input,
path: []
};
}
}
).refine(
(val) => {
const [, uuid] = val.split("--");
return import_v42.z.uuid().safeParse(uuid).success;
},
{
error: (issue) => {
const val = issue.input;
const [type] = val.split("--");
const typeName = type in stixTypeToTypeName ? stixTypeToTypeName[type] : "STIX";
return {
code: "custom",
message: `Invalid STIX Identifier for ${typeName} object: contains invalid UUIDv4 format`,
input: issue.input,
path: []
};
}
}
).meta({
description: "Represents identifiers across the CTI specifications. The format consists of the name of the top-level object being identified, followed by two dashes (--), followed by a UUIDv4."
});
// src/schemas/common/property-schemas/stix-granular-marking.ts
var granularMarkingSchema = import_zod2.z.object({
lang: nonEmptyRequiredString.optional().meta({
description: "The lang property identifies the language of the text identified by this marking. The value of the lang property, if present, MUST be an [RFC5646] language code. If the marking_ref property is not present, this property MUST be present. If the marking_ref property is present, this property MUST NOT be present."
}),
marking_ref: stixIdentifierSchema.optional().meta({
description: "The marking_ref property specifies the ID of the marking-definition object that describes the marking. If the lang property is not present, this property MUST be present. If the lang property is present, this property MUST NOT be present."
}),
selectors: stixListOfString.meta({
description: "The selectors property specifies a list of selectors for content contained within the STIX Object in which this property appears."
})
}).check((ctx) => {
const { lang, marking_ref } = ctx.value;
const hasLang = lang !== void 0;
const hasMarkingRef = marking_ref !== void 0;
if (hasLang && hasMarkingRef) {
ctx.issues.push({
path: ["lang"],
message: "If the marking_ref property is present, the lang property MUST NOT be present.",
code: "custom",
input: {
lang: ctx.value.lang,
marking_ref: ctx.value.marking_ref
}
});
ctx.issues.push({
path: ["marking_ref"],
message: "If the lang property is present, the marking_ref property MUST NOT be present.",
code: "custom",
input: {
lang: ctx.value.lang,
marking_ref: ctx.value.marking_ref
}
});
} else if (!hasLang && !hasMarkingRef) {
ctx.issues.push({
path: ["lang"],
message: "If the marking_ref property is not present, the lang property MUST be present.",
code: "custom",
input: {
lang: ctx.value.lang,
marking_ref: ctx.value.marking_ref
}
});
ctx.issues.push({
path: ["marking_ref"],
message: "If the lang property is not present, the marking_ref property MUST be present.",
code: "custom",
input: {
lang: ctx.value.lang,
marking_ref: ctx.value.marking_ref
}
});
}
}).meta({
description: "The `granular-marking` type defines how the `marking-definition` object referenced by the **marking_ref** property or a language specified by the **lang** property applies to a set of content identified by the list of selectors in the selectors property."
});
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
granularMarkingSchema
});