From 86e9f48e7eefaf0b47b2124e343a468e54e1711a Mon Sep 17 00:00:00 2001 From: miccy <9729864+miccy@users.noreply.github.com> Date: Tue, 28 Apr 2026 12:58:18 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20[security]=20replace=20Date.now(?= =?UTF-8?q?)=20with=20randomUUID()=20for=20STIX=20bundle=20IDs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STIX 2.1 bundle IDs should be unique and ideally non-predictable. Replacing Date.now() with crypto.randomUUID() ensures uniqueness and adheres to security best practices for identifier generation. --- packages/engine/src/extractor/ioc.test.ts | 22 ++++++++++++++++++++++ packages/engine/src/extractor/ioc.ts | 4 +++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/engine/src/extractor/ioc.test.ts diff --git a/packages/engine/src/extractor/ioc.test.ts b/packages/engine/src/extractor/ioc.test.ts new file mode 100644 index 0000000..1edb75f --- /dev/null +++ b/packages/engine/src/extractor/ioc.test.ts @@ -0,0 +1,22 @@ +import { expect, test } from "bun:test"; +import { extractStixBundle, type RawIOC } from "./ioc"; + +test("extractStixBundle should generate a valid UUIDv4 for the bundle ID", () => { + const iocs: RawIOC[] = [ + { + type: "hash", + value: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + confidence: "confirmed", + }, + ]; + const bundle = extractStixBundle(iocs) as { id: string }; + + // STIX bundle ID should be "bundle--" + expect(bundle.id).toStartWith("bundle--"); + const uuid = bundle.id.replace("bundle--", ""); + + // UUIDv4 regex + const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + + expect(uuid).toMatch(uuidV4Regex); +}); diff --git a/packages/engine/src/extractor/ioc.ts b/packages/engine/src/extractor/ioc.ts index cfc29e5..03cb486 100644 --- a/packages/engine/src/extractor/ioc.ts +++ b/packages/engine/src/extractor/ioc.ts @@ -4,6 +4,8 @@ * STIX 2.1 spec: https://docs.oasis-open.org/cti/stix/v2.1/ */ +import { randomUUID } from "node:crypto"; + export interface RawIOC { type: 'domain' | 'hash' | 'url' | 'ip' | 'file' | 'package' | 'email' value: string @@ -133,7 +135,7 @@ export function extractStixBundle(iocs: RawIOC[], malware = 'unknown'): object { const indicators = iocs.map((i) => iocToStix(i, malware)) return { type: 'bundle', - id: `bundle--${Date.now()}`, + id: `bundle--${randomUUID()}`, objects: [ { type: 'marking-definition',