Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/logger.js';

import {
stixBundleSchema,
stixBundleBaseSchema,
type AttackObject,
type StixBundle,
} from './schemas/sdo/stix-bundle.schema.js';
Expand Down Expand Up @@ -202,7 +202,7 @@ function parseStixBundle(rawData: StixBundle, parsingMode: ParsingMode): AttackO
const validObjects: AttackObject[] = [];

// Validate the bundle's top-level properties
const baseBundleValidationResults = stixBundleSchema
const baseBundleValidationResults = stixBundleBaseSchema
.pick({
id: true,
type: true,
Expand Down
32 changes: 18 additions & 14 deletions src/schemas/sdo/stix-bundle.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@ export type AttackObjects = z.infer<typeof attackObjectsSchema>;
//
//==============================================================================

export const stixBundleSchema = z
// Base schema without refinements so it can be composed with `.pick()`, `.extend()`, etc.
// Zod v4 forbids `.pick()` on schemas containing refinements (`.check()`), so the
// refinements below are attached to `stixBundleSchema` rather than this base.
export const stixBundleBaseSchema = z
.object({
id: createStixIdValidator('bundle'),
type: createStixTypeValidator('bundle'),
Expand Down Expand Up @@ -190,20 +193,21 @@ export const stixBundleSchema = z
description:
'A Bundle is a collection of arbitrary STIX Objects grouped together in a single container. A Bundle does not have any semantic meaning and the objects contained within the Bundle are not considered related by virtue of being in the same Bundle. A STIX Bundle Object is not a STIX Object but makes use of the type and id Common Properties.',
})
.strict()
.check((ctx) => {
// Validate that the first object is 'x-mitre-collection' and only one collection exists
validateXMitreCollection()(ctx);
.strict();

// Validate that all IDs referenced in 'x_mitre_contents' are present in 'objects' array
validateXMitreContentsReferences()(ctx);
export const stixBundleSchema = stixBundleBaseSchema.check((ctx) => {
// Validate that the first object is 'x-mitre-collection' and only one collection exists
validateXMitreCollection()(ctx);

// Validate that no duplicate objects are present in 'objects' array
validateNoDuplicates(
['objects'],
['id'],
'Duplicate object with id "{id}" found. Each object in the bundle must have a unique id.',
)(ctx);
});
// Validate that all IDs referenced in 'x_mitre_contents' are present in 'objects' array
validateXMitreContentsReferences()(ctx);

// Validate that no duplicate objects are present in 'objects' array
validateNoDuplicates(
['objects'],
['id'],
'Duplicate object with id "{id}" found. Each object in the bundle must have a unique id.',
)(ctx);
});

export type StixBundle = z.infer<typeof stixBundleSchema>;
Loading