@cyvest/cyvest-js 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +113 -111
- package/dist/index.d.ts +113 -111
- package/dist/index.js +212 -39
- package/dist/index.mjs +212 -38
- package/package.json +5 -5
- package/src/finders.ts +29 -20
- package/src/types.generated.ts +108 -99
- package/tests/getters-finders.test.ts +38 -18
- package/tests/graph.test.ts +19 -10
- package/vitest.config.ts +8 -0
package/dist/index.js
CHANGED
|
@@ -45,7 +45,6 @@ __export(index_exports, {
|
|
|
45
45
|
findExternalObservables: () => findExternalObservables,
|
|
46
46
|
findInternalObservables: () => findInternalObservables,
|
|
47
47
|
findLeafObservables: () => findLeafObservables,
|
|
48
|
-
findManuallyScored: () => findManuallyScored,
|
|
49
48
|
findObservablesAtLeast: () => findObservablesAtLeast,
|
|
50
49
|
findObservablesByLevel: () => findObservablesByLevel,
|
|
51
50
|
findObservablesByType: () => findObservablesByType,
|
|
@@ -140,6 +139,97 @@ var import_ajv_formats = __toESM(require("ajv-formats"));
|
|
|
140
139
|
// ../../../schema/cyvest.schema.json
|
|
141
140
|
var cyvest_schema_default = {
|
|
142
141
|
$defs: {
|
|
142
|
+
AuditEvent: {
|
|
143
|
+
additionalProperties: true,
|
|
144
|
+
description: "Centralized audit event for investigation-level changes.",
|
|
145
|
+
properties: {
|
|
146
|
+
event_id: {
|
|
147
|
+
title: "Event Id",
|
|
148
|
+
type: "string"
|
|
149
|
+
},
|
|
150
|
+
timestamp: {
|
|
151
|
+
format: "date-time",
|
|
152
|
+
title: "Timestamp",
|
|
153
|
+
type: "string"
|
|
154
|
+
},
|
|
155
|
+
event_type: {
|
|
156
|
+
title: "Event Type",
|
|
157
|
+
type: "string"
|
|
158
|
+
},
|
|
159
|
+
actor: {
|
|
160
|
+
anyOf: [
|
|
161
|
+
{
|
|
162
|
+
type: "string"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: "null"
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
default: null,
|
|
169
|
+
title: "Actor"
|
|
170
|
+
},
|
|
171
|
+
reason: {
|
|
172
|
+
anyOf: [
|
|
173
|
+
{
|
|
174
|
+
type: "string"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
type: "null"
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
default: null,
|
|
181
|
+
title: "Reason"
|
|
182
|
+
},
|
|
183
|
+
tool: {
|
|
184
|
+
anyOf: [
|
|
185
|
+
{
|
|
186
|
+
type: "string"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: "null"
|
|
190
|
+
}
|
|
191
|
+
],
|
|
192
|
+
default: null,
|
|
193
|
+
title: "Tool"
|
|
194
|
+
},
|
|
195
|
+
object_type: {
|
|
196
|
+
anyOf: [
|
|
197
|
+
{
|
|
198
|
+
type: "string"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
type: "null"
|
|
202
|
+
}
|
|
203
|
+
],
|
|
204
|
+
default: null,
|
|
205
|
+
title: "Object Type"
|
|
206
|
+
},
|
|
207
|
+
object_key: {
|
|
208
|
+
anyOf: [
|
|
209
|
+
{
|
|
210
|
+
type: "string"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
type: "null"
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
default: null,
|
|
217
|
+
title: "Object Key"
|
|
218
|
+
},
|
|
219
|
+
details: {
|
|
220
|
+
additionalProperties: true,
|
|
221
|
+
title: "Details",
|
|
222
|
+
type: "object"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
required: [
|
|
226
|
+
"event_id",
|
|
227
|
+
"timestamp",
|
|
228
|
+
"event_type"
|
|
229
|
+
],
|
|
230
|
+
title: "AuditEvent",
|
|
231
|
+
type: "object"
|
|
232
|
+
},
|
|
143
233
|
Check: {
|
|
144
234
|
description: "Represents a verification step in the investigation.\n\nA check validates a specific aspect of the data under investigation\nand contributes to the overall investigation score.",
|
|
145
235
|
properties: {
|
|
@@ -171,20 +261,25 @@ var cyvest_schema_default = {
|
|
|
171
261
|
level: {
|
|
172
262
|
$ref: "#/$defs/Level"
|
|
173
263
|
},
|
|
174
|
-
|
|
264
|
+
origin_investigation_id: {
|
|
265
|
+
title: "Origin Investigation Id",
|
|
266
|
+
type: "string"
|
|
267
|
+
},
|
|
268
|
+
observable_links: {
|
|
175
269
|
items: {
|
|
176
|
-
|
|
270
|
+
$ref: "#/$defs/ObservableLink"
|
|
177
271
|
},
|
|
178
|
-
title: "
|
|
272
|
+
title: "Observable Links",
|
|
179
273
|
type: "array"
|
|
180
274
|
},
|
|
181
|
-
score_policy: {
|
|
182
|
-
$ref: "#/$defs/CheckScorePolicy",
|
|
183
|
-
default: "auto"
|
|
184
|
-
},
|
|
185
275
|
key: {
|
|
186
276
|
title: "Key",
|
|
187
277
|
type: "string"
|
|
278
|
+
},
|
|
279
|
+
score_display: {
|
|
280
|
+
readOnly: true,
|
|
281
|
+
title: "Score Display",
|
|
282
|
+
type: "string"
|
|
188
283
|
}
|
|
189
284
|
},
|
|
190
285
|
required: [
|
|
@@ -195,21 +290,14 @@ var cyvest_schema_default = {
|
|
|
195
290
|
"extra",
|
|
196
291
|
"score",
|
|
197
292
|
"level",
|
|
198
|
-
"
|
|
199
|
-
"
|
|
293
|
+
"origin_investigation_id",
|
|
294
|
+
"observable_links",
|
|
295
|
+
"key",
|
|
296
|
+
"score_display"
|
|
200
297
|
],
|
|
201
298
|
title: "Check",
|
|
202
299
|
type: "object"
|
|
203
300
|
},
|
|
204
|
-
CheckScorePolicy: {
|
|
205
|
-
description: "Controls how a check reacts to linked observables.",
|
|
206
|
-
enum: [
|
|
207
|
-
"auto",
|
|
208
|
-
"manual"
|
|
209
|
-
],
|
|
210
|
-
title: "CheckScorePolicy",
|
|
211
|
-
type: "string"
|
|
212
|
-
},
|
|
213
301
|
Container: {
|
|
214
302
|
additionalProperties: false,
|
|
215
303
|
description: "Groups checks and sub-containers for hierarchical organization.\n\nContainers allow structuring the investigation into logical sections\nwith aggregated scores and levels.",
|
|
@@ -419,14 +507,19 @@ var cyvest_schema_default = {
|
|
|
419
507
|
title: "Key",
|
|
420
508
|
type: "string"
|
|
421
509
|
},
|
|
422
|
-
|
|
423
|
-
description: "Checks that
|
|
510
|
+
check_links: {
|
|
511
|
+
description: "Checks that currently link to this observable (navigation-only).",
|
|
424
512
|
items: {
|
|
425
513
|
type: "string"
|
|
426
514
|
},
|
|
427
515
|
readOnly: true,
|
|
428
|
-
title: "
|
|
516
|
+
title: "Check Links",
|
|
429
517
|
type: "array"
|
|
518
|
+
},
|
|
519
|
+
score_display: {
|
|
520
|
+
readOnly: true,
|
|
521
|
+
title: "Score Display",
|
|
522
|
+
type: "string"
|
|
430
523
|
}
|
|
431
524
|
},
|
|
432
525
|
required: [
|
|
@@ -441,11 +534,40 @@ var cyvest_schema_default = {
|
|
|
441
534
|
"threat_intels",
|
|
442
535
|
"relationships",
|
|
443
536
|
"key",
|
|
444
|
-
"
|
|
537
|
+
"check_links",
|
|
538
|
+
"score_display"
|
|
445
539
|
],
|
|
446
540
|
title: "Observable",
|
|
447
541
|
type: "object"
|
|
448
542
|
},
|
|
543
|
+
ObservableLink: {
|
|
544
|
+
additionalProperties: false,
|
|
545
|
+
description: "Edge metadata for a Check\u2194Observable association.",
|
|
546
|
+
properties: {
|
|
547
|
+
observable_key: {
|
|
548
|
+
title: "Observable Key",
|
|
549
|
+
type: "string"
|
|
550
|
+
},
|
|
551
|
+
propagation_mode: {
|
|
552
|
+
$ref: "#/$defs/PropagationMode",
|
|
553
|
+
default: "LOCAL_ONLY"
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
required: [
|
|
557
|
+
"observable_key"
|
|
558
|
+
],
|
|
559
|
+
title: "ObservableLink",
|
|
560
|
+
type: "object"
|
|
561
|
+
},
|
|
562
|
+
PropagationMode: {
|
|
563
|
+
description: "Controls how a Check\u2194Observable link propagates across merged investigations.",
|
|
564
|
+
enum: [
|
|
565
|
+
"LOCAL_ONLY",
|
|
566
|
+
"GLOBAL"
|
|
567
|
+
],
|
|
568
|
+
title: "PropagationMode",
|
|
569
|
+
type: "string"
|
|
570
|
+
},
|
|
449
571
|
Relationship: {
|
|
450
572
|
description: "Represents a relationship between observables.",
|
|
451
573
|
properties: {
|
|
@@ -665,6 +787,11 @@ var cyvest_schema_default = {
|
|
|
665
787
|
key: {
|
|
666
788
|
title: "Key",
|
|
667
789
|
type: "string"
|
|
790
|
+
},
|
|
791
|
+
score_display: {
|
|
792
|
+
readOnly: true,
|
|
793
|
+
title: "Score Display",
|
|
794
|
+
type: "string"
|
|
668
795
|
}
|
|
669
796
|
},
|
|
670
797
|
required: [
|
|
@@ -675,7 +802,8 @@ var cyvest_schema_default = {
|
|
|
675
802
|
"score",
|
|
676
803
|
"level",
|
|
677
804
|
"taxonomies",
|
|
678
|
-
"key"
|
|
805
|
+
"key",
|
|
806
|
+
"score_display"
|
|
679
807
|
],
|
|
680
808
|
title: "ThreatIntel",
|
|
681
809
|
type: "object"
|
|
@@ -686,6 +814,24 @@ var cyvest_schema_default = {
|
|
|
686
814
|
additionalProperties: false,
|
|
687
815
|
description: "Schema for a complete serialized investigation.\n\nThis model describes the output of `serialize_investigation()` from\n`cyvest.io_serialization`. It is the top-level schema for exported investigations.\n\nEntity types reference the runtime models directly. When generating schemas with\n`mode='serialization'`, Pydantic respects field_serializer decorators and produces\nschemas matching the actual model_dump() output.",
|
|
688
816
|
properties: {
|
|
817
|
+
investigation_id: {
|
|
818
|
+
description: "Stable investigation identity (ULID).",
|
|
819
|
+
title: "Investigation Id",
|
|
820
|
+
type: "string"
|
|
821
|
+
},
|
|
822
|
+
investigation_name: {
|
|
823
|
+
anyOf: [
|
|
824
|
+
{
|
|
825
|
+
type: "string"
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
type: "null"
|
|
829
|
+
}
|
|
830
|
+
],
|
|
831
|
+
default: null,
|
|
832
|
+
description: "Optional human-readable investigation name.",
|
|
833
|
+
title: "Investigation Name"
|
|
834
|
+
},
|
|
689
835
|
started_at: {
|
|
690
836
|
description: "Investigation start time (UTC).",
|
|
691
837
|
format: "date-time",
|
|
@@ -714,6 +860,14 @@ var cyvest_schema_default = {
|
|
|
714
860
|
title: "Whitelists",
|
|
715
861
|
type: "array"
|
|
716
862
|
},
|
|
863
|
+
event_log: {
|
|
864
|
+
description: "Append-only investigation audit log.",
|
|
865
|
+
items: {
|
|
866
|
+
$ref: "#/$defs/AuditEvent"
|
|
867
|
+
},
|
|
868
|
+
title: "Event Log",
|
|
869
|
+
type: "array"
|
|
870
|
+
},
|
|
717
871
|
observables: {
|
|
718
872
|
additionalProperties: {
|
|
719
873
|
$ref: "#/$defs/Observable"
|
|
@@ -779,9 +933,16 @@ var cyvest_schema_default = {
|
|
|
779
933
|
data_extraction: {
|
|
780
934
|
$ref: "#/$defs/DataExtractionSchema",
|
|
781
935
|
description: "Data extraction metadata."
|
|
936
|
+
},
|
|
937
|
+
score_display: {
|
|
938
|
+
description: "Global investigation score formatted as fixed-point x.xx.",
|
|
939
|
+
readOnly: true,
|
|
940
|
+
title: "Score Display",
|
|
941
|
+
type: "string"
|
|
782
942
|
}
|
|
783
943
|
},
|
|
784
944
|
required: [
|
|
945
|
+
"investigation_id",
|
|
785
946
|
"started_at",
|
|
786
947
|
"score",
|
|
787
948
|
"level",
|
|
@@ -795,7 +956,8 @@ var cyvest_schema_default = {
|
|
|
795
956
|
"containers",
|
|
796
957
|
"stats",
|
|
797
958
|
"stats_checks",
|
|
798
|
-
"data_extraction"
|
|
959
|
+
"data_extraction",
|
|
960
|
+
"score_display"
|
|
799
961
|
],
|
|
800
962
|
title: "Cyvest Investigation",
|
|
801
963
|
type: "object"
|
|
@@ -1275,17 +1437,6 @@ function findChecksByCheckId(inv, checkId) {
|
|
|
1275
1437
|
}
|
|
1276
1438
|
return result;
|
|
1277
1439
|
}
|
|
1278
|
-
function findManuallyScored(inv) {
|
|
1279
|
-
const result = [];
|
|
1280
|
-
for (const checks of Object.values(inv.checks)) {
|
|
1281
|
-
for (const check of checks) {
|
|
1282
|
-
if (check.score_policy === "manual") {
|
|
1283
|
-
result.push(check);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
return result;
|
|
1288
|
-
}
|
|
1289
1440
|
function findThreatIntelBySource(inv, source) {
|
|
1290
1441
|
const normalizedSource = source.trim().toLowerCase();
|
|
1291
1442
|
return Object.values(inv.threat_intels).filter(
|
|
@@ -1328,13 +1479,32 @@ function findContainersAtLeast(inv, minLevel2) {
|
|
|
1328
1479
|
}
|
|
1329
1480
|
function getChecksForObservable(inv, observableKey) {
|
|
1330
1481
|
const result = [];
|
|
1482
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1483
|
+
const checkLookup = /* @__PURE__ */ new Map();
|
|
1331
1484
|
for (const checks of Object.values(inv.checks)) {
|
|
1332
1485
|
for (const check of checks) {
|
|
1333
|
-
|
|
1486
|
+
checkLookup.set(check.key, check);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
const observable = inv.observables[observableKey];
|
|
1490
|
+
if (observable) {
|
|
1491
|
+
for (const checkKey of observable.check_links) {
|
|
1492
|
+
const check = checkLookup.get(checkKey);
|
|
1493
|
+
if (check && !seen.has(check.key)) {
|
|
1334
1494
|
result.push(check);
|
|
1495
|
+
seen.add(check.key);
|
|
1335
1496
|
}
|
|
1336
1497
|
}
|
|
1337
1498
|
}
|
|
1499
|
+
for (const check of checkLookup.values()) {
|
|
1500
|
+
if (seen.has(check.key)) {
|
|
1501
|
+
continue;
|
|
1502
|
+
}
|
|
1503
|
+
if (check.observable_links.some((link) => link.observable_key === observableKey)) {
|
|
1504
|
+
result.push(check);
|
|
1505
|
+
seen.add(check.key);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1338
1508
|
return result;
|
|
1339
1509
|
}
|
|
1340
1510
|
function getThreatIntelsForObservable(inv, observableKey) {
|
|
@@ -1350,7 +1520,11 @@ function getObservablesForCheck(inv, checkKey) {
|
|
|
1350
1520
|
for (const checks of Object.values(inv.checks)) {
|
|
1351
1521
|
for (const check of checks) {
|
|
1352
1522
|
if (check.key === checkKey) {
|
|
1353
|
-
|
|
1523
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1524
|
+
for (const link of check.observable_links) {
|
|
1525
|
+
keys.add(link.observable_key);
|
|
1526
|
+
}
|
|
1527
|
+
return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
|
|
1354
1528
|
}
|
|
1355
1529
|
}
|
|
1356
1530
|
}
|
|
@@ -1723,7 +1897,6 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1723
1897
|
findExternalObservables,
|
|
1724
1898
|
findInternalObservables,
|
|
1725
1899
|
findLeafObservables,
|
|
1726
|
-
findManuallyScored,
|
|
1727
1900
|
findObservablesAtLeast,
|
|
1728
1901
|
findObservablesByLevel,
|
|
1729
1902
|
findObservablesByType,
|