@cyvest/cyvest-js 3.2.0 → 4.1.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 +55 -33
- package/dist/index.d.ts +55 -33
- package/dist/index.js +191 -71
- package/dist/index.mjs +191 -69
- package/package.json +5 -5
- package/src/finders.ts +29 -20
- package/src/getters.ts +0 -10
- package/src/types.generated.ts +54 -18
- package/tests/getters-finders.test.ts +40 -24
- package/tests/graph.test.ts +21 -16
- 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,
|
|
@@ -104,7 +103,6 @@ __export(index_exports, {
|
|
|
104
103
|
getRelatedObservablesByType: () => getRelatedObservablesByType,
|
|
105
104
|
getRelationshipsForObservable: () => getRelationshipsForObservable,
|
|
106
105
|
getStats: () => getStats,
|
|
107
|
-
getStatsChecks: () => getStatsChecks,
|
|
108
106
|
getSuspiciousChecks: () => getSuspiciousChecks,
|
|
109
107
|
getSuspiciousObservables: () => getSuspiciousObservables,
|
|
110
108
|
getThreatIntel: () => getThreatIntel,
|
|
@@ -140,6 +138,97 @@ var import_ajv_formats = __toESM(require("ajv-formats"));
|
|
|
140
138
|
// ../../../schema/cyvest.schema.json
|
|
141
139
|
var cyvest_schema_default = {
|
|
142
140
|
$defs: {
|
|
141
|
+
AuditEvent: {
|
|
142
|
+
additionalProperties: true,
|
|
143
|
+
description: "Centralized audit event for investigation-level changes.",
|
|
144
|
+
properties: {
|
|
145
|
+
event_id: {
|
|
146
|
+
title: "Event Id",
|
|
147
|
+
type: "string"
|
|
148
|
+
},
|
|
149
|
+
timestamp: {
|
|
150
|
+
format: "date-time",
|
|
151
|
+
title: "Timestamp",
|
|
152
|
+
type: "string"
|
|
153
|
+
},
|
|
154
|
+
event_type: {
|
|
155
|
+
title: "Event Type",
|
|
156
|
+
type: "string"
|
|
157
|
+
},
|
|
158
|
+
actor: {
|
|
159
|
+
anyOf: [
|
|
160
|
+
{
|
|
161
|
+
type: "string"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
type: "null"
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
default: null,
|
|
168
|
+
title: "Actor"
|
|
169
|
+
},
|
|
170
|
+
reason: {
|
|
171
|
+
anyOf: [
|
|
172
|
+
{
|
|
173
|
+
type: "string"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
type: "null"
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
default: null,
|
|
180
|
+
title: "Reason"
|
|
181
|
+
},
|
|
182
|
+
tool: {
|
|
183
|
+
anyOf: [
|
|
184
|
+
{
|
|
185
|
+
type: "string"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
type: "null"
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
default: null,
|
|
192
|
+
title: "Tool"
|
|
193
|
+
},
|
|
194
|
+
object_type: {
|
|
195
|
+
anyOf: [
|
|
196
|
+
{
|
|
197
|
+
type: "string"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: "null"
|
|
201
|
+
}
|
|
202
|
+
],
|
|
203
|
+
default: null,
|
|
204
|
+
title: "Object Type"
|
|
205
|
+
},
|
|
206
|
+
object_key: {
|
|
207
|
+
anyOf: [
|
|
208
|
+
{
|
|
209
|
+
type: "string"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
type: "null"
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
default: null,
|
|
216
|
+
title: "Object Key"
|
|
217
|
+
},
|
|
218
|
+
details: {
|
|
219
|
+
additionalProperties: true,
|
|
220
|
+
title: "Details",
|
|
221
|
+
type: "object"
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
required: [
|
|
225
|
+
"event_id",
|
|
226
|
+
"timestamp",
|
|
227
|
+
"event_type"
|
|
228
|
+
],
|
|
229
|
+
title: "AuditEvent",
|
|
230
|
+
type: "object"
|
|
231
|
+
},
|
|
143
232
|
Check: {
|
|
144
233
|
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
234
|
properties: {
|
|
@@ -171,17 +260,17 @@ var cyvest_schema_default = {
|
|
|
171
260
|
level: {
|
|
172
261
|
$ref: "#/$defs/Level"
|
|
173
262
|
},
|
|
174
|
-
|
|
263
|
+
origin_investigation_id: {
|
|
264
|
+
title: "Origin Investigation Id",
|
|
265
|
+
type: "string"
|
|
266
|
+
},
|
|
267
|
+
observable_links: {
|
|
175
268
|
items: {
|
|
176
|
-
|
|
269
|
+
$ref: "#/$defs/ObservableLink"
|
|
177
270
|
},
|
|
178
|
-
title: "
|
|
271
|
+
title: "Observable Links",
|
|
179
272
|
type: "array"
|
|
180
273
|
},
|
|
181
|
-
score_policy: {
|
|
182
|
-
$ref: "#/$defs/CheckScorePolicy",
|
|
183
|
-
default: "auto"
|
|
184
|
-
},
|
|
185
274
|
key: {
|
|
186
275
|
title: "Key",
|
|
187
276
|
type: "string"
|
|
@@ -200,22 +289,14 @@ var cyvest_schema_default = {
|
|
|
200
289
|
"extra",
|
|
201
290
|
"score",
|
|
202
291
|
"level",
|
|
203
|
-
"
|
|
292
|
+
"origin_investigation_id",
|
|
293
|
+
"observable_links",
|
|
204
294
|
"key",
|
|
205
295
|
"score_display"
|
|
206
296
|
],
|
|
207
297
|
title: "Check",
|
|
208
298
|
type: "object"
|
|
209
299
|
},
|
|
210
|
-
CheckScorePolicy: {
|
|
211
|
-
description: "Controls how a check reacts to linked observables.",
|
|
212
|
-
enum: [
|
|
213
|
-
"auto",
|
|
214
|
-
"manual"
|
|
215
|
-
],
|
|
216
|
-
title: "CheckScorePolicy",
|
|
217
|
-
type: "string"
|
|
218
|
-
},
|
|
219
300
|
Container: {
|
|
220
301
|
additionalProperties: false,
|
|
221
302
|
description: "Groups checks and sub-containers for hierarchical organization.\n\nContainers allow structuring the investigation into logical sections\nwith aggregated scores and levels.",
|
|
@@ -276,6 +357,10 @@ var cyvest_schema_default = {
|
|
|
276
357
|
root_type: {
|
|
277
358
|
anyOf: [
|
|
278
359
|
{
|
|
360
|
+
enum: [
|
|
361
|
+
"file",
|
|
362
|
+
"artifact"
|
|
363
|
+
],
|
|
279
364
|
type: "string"
|
|
280
365
|
},
|
|
281
366
|
{
|
|
@@ -286,13 +371,13 @@ var cyvest_schema_default = {
|
|
|
286
371
|
description: "Root observable type used during data extraction.",
|
|
287
372
|
title: "Root Type"
|
|
288
373
|
},
|
|
289
|
-
|
|
374
|
+
score_mode_obs: {
|
|
290
375
|
$ref: "#/$defs/ScoreMode",
|
|
291
|
-
description: "
|
|
376
|
+
description: "Observable score aggregation mode: 'max' takes highest score, 'sum' adds all scores."
|
|
292
377
|
}
|
|
293
378
|
},
|
|
294
379
|
required: [
|
|
295
|
-
"
|
|
380
|
+
"score_mode_obs"
|
|
296
381
|
],
|
|
297
382
|
title: "DataExtractionSchema",
|
|
298
383
|
type: "object"
|
|
@@ -425,13 +510,13 @@ var cyvest_schema_default = {
|
|
|
425
510
|
title: "Key",
|
|
426
511
|
type: "string"
|
|
427
512
|
},
|
|
428
|
-
|
|
429
|
-
description: "Checks that
|
|
513
|
+
check_links: {
|
|
514
|
+
description: "Checks that currently link to this observable (navigation-only).",
|
|
430
515
|
items: {
|
|
431
516
|
type: "string"
|
|
432
517
|
},
|
|
433
518
|
readOnly: true,
|
|
434
|
-
title: "
|
|
519
|
+
title: "Check Links",
|
|
435
520
|
type: "array"
|
|
436
521
|
},
|
|
437
522
|
score_display: {
|
|
@@ -452,12 +537,40 @@ var cyvest_schema_default = {
|
|
|
452
537
|
"threat_intels",
|
|
453
538
|
"relationships",
|
|
454
539
|
"key",
|
|
455
|
-
"
|
|
540
|
+
"check_links",
|
|
456
541
|
"score_display"
|
|
457
542
|
],
|
|
458
543
|
title: "Observable",
|
|
459
544
|
type: "object"
|
|
460
545
|
},
|
|
546
|
+
ObservableLink: {
|
|
547
|
+
additionalProperties: false,
|
|
548
|
+
description: "Edge metadata for a Check\u2194Observable association.",
|
|
549
|
+
properties: {
|
|
550
|
+
observable_key: {
|
|
551
|
+
title: "Observable Key",
|
|
552
|
+
type: "string"
|
|
553
|
+
},
|
|
554
|
+
propagation_mode: {
|
|
555
|
+
$ref: "#/$defs/PropagationMode",
|
|
556
|
+
default: "LOCAL_ONLY"
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
required: [
|
|
560
|
+
"observable_key"
|
|
561
|
+
],
|
|
562
|
+
title: "ObservableLink",
|
|
563
|
+
type: "object"
|
|
564
|
+
},
|
|
565
|
+
PropagationMode: {
|
|
566
|
+
description: "Controls how a Check\u2194Observable link propagates across merged investigations.",
|
|
567
|
+
enum: [
|
|
568
|
+
"LOCAL_ONLY",
|
|
569
|
+
"GLOBAL"
|
|
570
|
+
],
|
|
571
|
+
title: "PropagationMode",
|
|
572
|
+
type: "string"
|
|
573
|
+
},
|
|
461
574
|
Relationship: {
|
|
462
575
|
description: "Represents a relationship between observables.",
|
|
463
576
|
properties: {
|
|
@@ -617,28 +730,6 @@ var cyvest_schema_default = {
|
|
|
617
730
|
title: "StatisticsSchema",
|
|
618
731
|
type: "object"
|
|
619
732
|
},
|
|
620
|
-
StatsChecksSchema: {
|
|
621
|
-
additionalProperties: false,
|
|
622
|
-
description: "Schema for check statistics summary.",
|
|
623
|
-
properties: {
|
|
624
|
-
checks: {
|
|
625
|
-
minimum: 0,
|
|
626
|
-
title: "Checks",
|
|
627
|
-
type: "integer"
|
|
628
|
-
},
|
|
629
|
-
applied: {
|
|
630
|
-
minimum: 0,
|
|
631
|
-
title: "Applied",
|
|
632
|
-
type: "integer"
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
required: [
|
|
636
|
-
"checks",
|
|
637
|
-
"applied"
|
|
638
|
-
],
|
|
639
|
-
title: "StatsChecksSchema",
|
|
640
|
-
type: "object"
|
|
641
|
-
},
|
|
642
733
|
ThreatIntel: {
|
|
643
734
|
description: "Represents threat intelligence from an external source.\n\nThreat intelligence provides verdicts about observables from sources\nlike VirusTotal, URLScan.io, etc.",
|
|
644
735
|
properties: {
|
|
@@ -704,6 +795,24 @@ var cyvest_schema_default = {
|
|
|
704
795
|
additionalProperties: false,
|
|
705
796
|
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.",
|
|
706
797
|
properties: {
|
|
798
|
+
investigation_id: {
|
|
799
|
+
description: "Stable investigation identity (ULID).",
|
|
800
|
+
title: "Investigation Id",
|
|
801
|
+
type: "string"
|
|
802
|
+
},
|
|
803
|
+
investigation_name: {
|
|
804
|
+
anyOf: [
|
|
805
|
+
{
|
|
806
|
+
type: "string"
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
type: "null"
|
|
810
|
+
}
|
|
811
|
+
],
|
|
812
|
+
default: null,
|
|
813
|
+
description: "Optional human-readable investigation name.",
|
|
814
|
+
title: "Investigation Name"
|
|
815
|
+
},
|
|
707
816
|
started_at: {
|
|
708
817
|
description: "Investigation start time (UTC).",
|
|
709
818
|
format: "date-time",
|
|
@@ -732,6 +841,14 @@ var cyvest_schema_default = {
|
|
|
732
841
|
title: "Whitelists",
|
|
733
842
|
type: "array"
|
|
734
843
|
},
|
|
844
|
+
event_log: {
|
|
845
|
+
description: "Append-only investigation audit log.",
|
|
846
|
+
items: {
|
|
847
|
+
$ref: "#/$defs/AuditEvent"
|
|
848
|
+
},
|
|
849
|
+
title: "Event Log",
|
|
850
|
+
type: "array"
|
|
851
|
+
},
|
|
735
852
|
observables: {
|
|
736
853
|
additionalProperties: {
|
|
737
854
|
$ref: "#/$defs/Observable"
|
|
@@ -790,10 +907,6 @@ var cyvest_schema_default = {
|
|
|
790
907
|
$ref: "#/$defs/StatisticsSchema",
|
|
791
908
|
description: "Investigation statistics summary."
|
|
792
909
|
},
|
|
793
|
-
stats_checks: {
|
|
794
|
-
$ref: "#/$defs/StatsChecksSchema",
|
|
795
|
-
description: "Check statistics summary."
|
|
796
|
-
},
|
|
797
910
|
data_extraction: {
|
|
798
911
|
$ref: "#/$defs/DataExtractionSchema",
|
|
799
912
|
description: "Data extraction metadata."
|
|
@@ -806,6 +919,7 @@ var cyvest_schema_default = {
|
|
|
806
919
|
}
|
|
807
920
|
},
|
|
808
921
|
required: [
|
|
922
|
+
"investigation_id",
|
|
809
923
|
"started_at",
|
|
810
924
|
"score",
|
|
811
925
|
"level",
|
|
@@ -818,7 +932,6 @@ var cyvest_schema_default = {
|
|
|
818
932
|
"enrichments",
|
|
819
933
|
"containers",
|
|
820
934
|
"stats",
|
|
821
|
-
"stats_checks",
|
|
822
935
|
"data_extraction",
|
|
823
936
|
"score_display"
|
|
824
937
|
],
|
|
@@ -1191,9 +1304,6 @@ function getWhitelists(inv) {
|
|
|
1191
1304
|
function getStats(inv) {
|
|
1192
1305
|
return inv.stats;
|
|
1193
1306
|
}
|
|
1194
|
-
function getStatsChecks(inv) {
|
|
1195
|
-
return inv.stats_checks;
|
|
1196
|
-
}
|
|
1197
1307
|
function getDataExtraction(inv) {
|
|
1198
1308
|
return inv.data_extraction;
|
|
1199
1309
|
}
|
|
@@ -1300,17 +1410,6 @@ function findChecksByCheckId(inv, checkId) {
|
|
|
1300
1410
|
}
|
|
1301
1411
|
return result;
|
|
1302
1412
|
}
|
|
1303
|
-
function findManuallyScored(inv) {
|
|
1304
|
-
const result = [];
|
|
1305
|
-
for (const checks of Object.values(inv.checks)) {
|
|
1306
|
-
for (const check of checks) {
|
|
1307
|
-
if (check.score_policy === "manual") {
|
|
1308
|
-
result.push(check);
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
return result;
|
|
1313
|
-
}
|
|
1314
1413
|
function findThreatIntelBySource(inv, source) {
|
|
1315
1414
|
const normalizedSource = source.trim().toLowerCase();
|
|
1316
1415
|
return Object.values(inv.threat_intels).filter(
|
|
@@ -1353,13 +1452,32 @@ function findContainersAtLeast(inv, minLevel2) {
|
|
|
1353
1452
|
}
|
|
1354
1453
|
function getChecksForObservable(inv, observableKey) {
|
|
1355
1454
|
const result = [];
|
|
1455
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1456
|
+
const checkLookup = /* @__PURE__ */ new Map();
|
|
1356
1457
|
for (const checks of Object.values(inv.checks)) {
|
|
1357
1458
|
for (const check of checks) {
|
|
1358
|
-
|
|
1459
|
+
checkLookup.set(check.key, check);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
const observable = inv.observables[observableKey];
|
|
1463
|
+
if (observable) {
|
|
1464
|
+
for (const checkKey of observable.check_links) {
|
|
1465
|
+
const check = checkLookup.get(checkKey);
|
|
1466
|
+
if (check && !seen.has(check.key)) {
|
|
1359
1467
|
result.push(check);
|
|
1468
|
+
seen.add(check.key);
|
|
1360
1469
|
}
|
|
1361
1470
|
}
|
|
1362
1471
|
}
|
|
1472
|
+
for (const check of checkLookup.values()) {
|
|
1473
|
+
if (seen.has(check.key)) {
|
|
1474
|
+
continue;
|
|
1475
|
+
}
|
|
1476
|
+
if (check.observable_links.some((link) => link.observable_key === observableKey)) {
|
|
1477
|
+
result.push(check);
|
|
1478
|
+
seen.add(check.key);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1363
1481
|
return result;
|
|
1364
1482
|
}
|
|
1365
1483
|
function getThreatIntelsForObservable(inv, observableKey) {
|
|
@@ -1375,7 +1493,11 @@ function getObservablesForCheck(inv, checkKey) {
|
|
|
1375
1493
|
for (const checks of Object.values(inv.checks)) {
|
|
1376
1494
|
for (const check of checks) {
|
|
1377
1495
|
if (check.key === checkKey) {
|
|
1378
|
-
|
|
1496
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1497
|
+
for (const link of check.observable_links) {
|
|
1498
|
+
keys.add(link.observable_key);
|
|
1499
|
+
}
|
|
1500
|
+
return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
|
|
1379
1501
|
}
|
|
1380
1502
|
}
|
|
1381
1503
|
}
|
|
@@ -1748,7 +1870,6 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1748
1870
|
findExternalObservables,
|
|
1749
1871
|
findInternalObservables,
|
|
1750
1872
|
findLeafObservables,
|
|
1751
|
-
findManuallyScored,
|
|
1752
1873
|
findObservablesAtLeast,
|
|
1753
1874
|
findObservablesByLevel,
|
|
1754
1875
|
findObservablesByType,
|
|
@@ -1807,7 +1928,6 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1807
1928
|
getRelatedObservablesByType,
|
|
1808
1929
|
getRelationshipsForObservable,
|
|
1809
1930
|
getStats,
|
|
1810
|
-
getStatsChecks,
|
|
1811
1931
|
getSuspiciousChecks,
|
|
1812
1932
|
getSuspiciousObservables,
|
|
1813
1933
|
getThreatIntel,
|