diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 2e7320e4..3a5cf55d 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -11,8 +11,8 @@ jobs: name: static-checks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: '18.x' - run: npm install diff --git a/NOTICE.txt b/NOTICE.txt index ed61cf6b..f9f5e148 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,4 +1,4 @@ -Copyright 2020-2023 MITRE Engenuity. Approved for public release. Document number CT0020 and public release case number 22-3206. +Copyright 2020-2024 MITRE Engenuity. Approved for public release. Document number CT0020 and public release case number 22-3206. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 8c0965ec..e0efe502 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,7 @@ The workflow is defined in `.github/workflows/ci-workflow.yml` ## Notice -Copyright 2020-2023 MITRE Engenuity. Approved for public release. Document number CT0020 +Copyright 2020-2024 MITRE Engenuity. Approved for public release. Document number CT0020 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/app/api/definitions/paths/assets-paths.yml b/app/api/definitions/paths/assets-paths.yml index 04f24759..5cec7e1f 100644 --- a/app/api/definitions/paths/assets-paths.yml +++ b/app/api/definitions/paths/assets-paths.yml @@ -79,7 +79,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/attack-objects-paths.yml b/app/api/definitions/paths/attack-objects-paths.yml index b85ba2a6..13051727 100644 --- a/app/api/definitions/paths/attack-objects-paths.yml +++ b/app/api/definitions/paths/attack-objects-paths.yml @@ -68,7 +68,7 @@ paths: - name: search in: query description: | - Only return ATT&CK objects where the provided search text occurs in the `name` or `description`. + Only return ATT&CK objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/campaigns-paths.yml b/app/api/definitions/paths/campaigns-paths.yml index da03c2c0..c1dca1e4 100644 --- a/app/api/definitions/paths/campaigns-paths.yml +++ b/app/api/definitions/paths/campaigns-paths.yml @@ -55,7 +55,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/data-sources-paths.yml b/app/api/definitions/paths/data-sources-paths.yml index 20d6320a..f45d14ce 100644 --- a/app/api/definitions/paths/data-sources-paths.yml +++ b/app/api/definitions/paths/data-sources-paths.yml @@ -79,7 +79,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/groups-paths.yml b/app/api/definitions/paths/groups-paths.yml index 171cd2c3..c9e31c30 100644 --- a/app/api/definitions/paths/groups-paths.yml +++ b/app/api/definitions/paths/groups-paths.yml @@ -55,7 +55,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/mitigations-paths.yml b/app/api/definitions/paths/mitigations-paths.yml index 784a956d..a773e6d1 100644 --- a/app/api/definitions/paths/mitigations-paths.yml +++ b/app/api/definitions/paths/mitigations-paths.yml @@ -67,7 +67,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/software-paths.yml b/app/api/definitions/paths/software-paths.yml index db214d77..efc3ac7a 100644 --- a/app/api/definitions/paths/software-paths.yml +++ b/app/api/definitions/paths/software-paths.yml @@ -79,7 +79,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/tactics-paths.yml b/app/api/definitions/paths/tactics-paths.yml index 8197a3b8..551ca023 100644 --- a/app/api/definitions/paths/tactics-paths.yml +++ b/app/api/definitions/paths/tactics-paths.yml @@ -67,7 +67,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/api/definitions/paths/techniques-paths.yml b/app/api/definitions/paths/techniques-paths.yml index 7cc5ce97..effaf3fb 100644 --- a/app/api/definitions/paths/techniques-paths.yml +++ b/app/api/definitions/paths/techniques-paths.yml @@ -80,7 +80,7 @@ paths: - name: search in: query description: | - Only return objects where the provided search text occurs in the `name` or `description`. + Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`. The search is case-insensitive. schema: type: string diff --git a/app/config/allowed-values.json b/app/config/allowed-values.json index b2a795af..dfa30588 100644 --- a/app/config/allowed-values.json +++ b/app/config/allowed-values.json @@ -13,12 +13,11 @@ "macOS", "Windows", "Network", - "Office 365", - "Azure AD", "SaaS", "IaaS", - "Google Workspace", - "Containers" + "Containers", + "Identity Provider", + "Office Suite" ] }, { @@ -159,11 +158,11 @@ "macOS", "Windows", "Network", - "Office 365", - "Azure AD", "IaaS", "SaaS", - "Containers" + "Containers", + "Identity Provider", + "Office Suite" ] }, { @@ -231,14 +230,13 @@ "allowedValues": [ "Containers", "Windows", - "Azure AD", "Linux", "macOS", "IaaS", "SaaS", - "Office 365", - "Google Workspace", - "Network" + "Network", + "Identity Provider", + "Office Suite" ] }, { diff --git a/app/services/attack-objects-service.js b/app/services/attack-objects-service.js index fbb10eae..8193b241 100644 --- a/app/services/attack-objects-service.js +++ b/app/services/attack-objects-service.js @@ -75,6 +75,7 @@ exports.retrieveAll = async function(options) { const match = { $match: { $or: [ + { 'workspace.attack_id': { '$regex': options.search, '$options': 'i' }}, { 'stix.name': { '$regex': options.search, '$options': 'i' } }, { 'stix.description': { '$regex': options.search, '$options': 'i' } } ] diff --git a/app/services/matrices-service.js b/app/services/matrices-service.js index ef8072fd..340acbe1 100644 --- a/app/services/matrices-service.js +++ b/app/services/matrices-service.js @@ -274,14 +274,14 @@ exports.retrieveTechniquesForMatrix = function(stixId, modified, callback) { for (const parentTechnique of parentTechniques) { parentTechnique.subtechniques = []; for (const subtechnique of subtechniques) { - if (subtechnique.workspace.attack_id.split(".")[0] === parentTechnique.workspace.attack_id) { + if (subtechnique.workspace.attack_id && subtechnique.workspace.attack_id.split(".")[0] === parentTechnique.workspace.attack_id) { parentTechnique.subtechniques.push(subtechnique); } } } // Add techniques to tactic & store tactic tactic.techniques = parentTechniques; - tacticsTechniques[tactic.stix.name] = tactic; + tacticsTechniques[tactic.stix.id] = tactic; } } return callback(null, tacticsTechniques); diff --git a/app/services/stix-bundles-service.js b/app/services/stix-bundles-service.js index ca154694..e577b849 100644 --- a/app/services/stix-bundles-service.js +++ b/app/services/stix-bundles-service.js @@ -208,7 +208,7 @@ exports.exportBundle = async function(options) { } // Put the primary objects in the bundle - // Also create a map of the objects added to the bundle (only use the id, since relationships only reference the id) + // Also create a map of the objects added to the bundle (use the id as the key, since relationships only reference the id) const objectsMap = new Map(); for (const primaryObject of primaryObjects) { bundle.objects.push(primaryObject.stix); @@ -342,6 +342,22 @@ exports.exportBundle = async function(options) { addAttackObjectToMap(secondaryObject); } + // Add groups to the bundle that are referenced by a campaign but are not referenced by a primary object + for (const relationship of allRelationships) { + if (relationship.stix.relationship_type === 'attributed-to') { + if (objectsMap.has(relationship.stix.source_ref) && !objectsMap.has(relationship.stix.target_ref)) { + // Add the group to the bundle + const groupObject = await getAttackObject(relationship.stix.target_ref); + if (groupObject.stix.type === 'intrusion-set' && secondaryObjectIsValid(groupObject)) { + groupObject.stix.x_mitre_domains = [ options.domain ]; + bundle.objects.push(groupObject.stix); + objectsMap.set(groupObject.stix.id, true); + // relationships will be added to the bundle later + } + } + } + } + // Data components have already been added to the bundle because they're referenced in a relationship // Get the data sources referenced by data components, using a map to eliminate duplicates const dataSourceIds = new Map(); diff --git a/app/tests/api/stix-bundles/stix-bundles.spec.js b/app/tests/api/stix-bundles/stix-bundles.spec.js index db1c66cc..5dc9000d 100644 --- a/app/tests/api/stix-bundles/stix-bundles.spec.js +++ b/app/tests/api/stix-bundles/stix-bundles.spec.js @@ -64,6 +64,10 @@ const initialObjectData = { "object_ref": "intrusion-set--8a831aaa-f3e0-47a3-bed8-a9ced744dd12", "object_modified": "2020-06-03T20:22:40.401Z" }, + { + "object_ref": "intrusion-set--ed0222fb-b970-4337-b9a2-62aeb02860e5", + "object_modified": "2023-05-02T20:19:40.401Z" + }, { "object_ref": "relationship--12098dee-27b3-4d0b-a15a-6b5955ba8879", "object_modified": "2019-09-04T14:32:13.000Z" @@ -76,6 +80,10 @@ const initialObjectData = { "object_ref": "campaign--a3038910-f8ca-4ba8-b116-21d0f333f231", "object_modified": "2020-07-03T20:22:40.401Z" }, + { + "object_ref": "campaign--649b389e-1f7a-4696-8a95-04d0851bd551", + "object_modified": "2020-07-03T20:22:40.401Z" + }, { "object_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "object_modified": "2017-06-01T00:00:00.000Z" @@ -127,7 +135,15 @@ const initialObjectData = { { "object_ref": "relationship--a5a80c31-0dde-4fd7-a520-a7593d21c954", "object_modified": "2021-06-08T14:00:00.000Z" - } + }, + { + "object_ref": "relationship--1e1c5e5a-2a3e-423f-b1d0-67b7dc5b90cc", + "object_modified": "2023-06-08T14:00:00.000Z" + }, + { + "object_ref": "relationship--d5426745-9530-485e-a757-d8c540f600f8", + "object_modified": "2021-06-06T14:00:00.000Z" + }, ] }, { @@ -343,6 +359,30 @@ const initialObjectData = { spec_version: "2.1", x_mitre_version: "1.2" }, + { + type: "intrusion-set", + id: "intrusion-set--ed0222fb-b970-4337-b9a2-62aeb02860e5", + created_by_ref: "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", + name: "Another group", + description: "This is another group. It isn't referenced by a technique, but is associated with a campaign", + object_marking_refs: [ + "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" + ], + external_references: [ + { + source_name: "mitre-attack", + url: "https://attack.mitre.org/groups/G0999", + external_id: "G0999" + } + ], + aliases: [ + "Some group alias" + ], + modified: "2023-05-02T20:19:40.401Z", + created: "2018-10-17T00:19:20.652Z", + spec_version: "2.1", + x_mitre_version: "1.2" + }, { type: "campaign", id: "campaign--a3038910-f8ca-4ba8-b116-21d0f333f231", @@ -371,6 +411,34 @@ const initialObjectData = { spec_version: "2.1", x_mitre_version: "1.2" }, + { + type: "campaign", + id: "campaign--649b389e-1f7a-4696-8a95-04d0851bd551", + created_by_ref: "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", + name: "campaign-2", + description: "This is another campaign", + first_seen: "2016-04-06T00:00:00.000Z", + last_seen: "2016-07-12T00:00:00.000Z", + x_mitre_first_seen_citation: "(Citation: Article 1)", + x_mitre_last_seen_citation: "(Citation: Article 2)", + object_marking_refs: [ + "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" + ], + external_references: [ + { + source_name: "mitre-attack", + url: "https://attack.mitre.org/campaigns/C0002", + external_id: "C0002" + } + ], + aliases: [ + "Another campaign name" + ], + modified: "2020-07-03T20:22:40.401Z", + created: "2018-11-17T00:14:20.652Z", + spec_version: "2.1", + x_mitre_version: "1.2" + }, { created_by_ref: "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", object_marking_refs: [ @@ -534,6 +602,21 @@ const initialObjectData = { spec_version: "2.1" }, { + created_by_ref: "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", + object_marking_refs: [ + "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" + ], + source_ref: "campaign--649b389e-1f7a-4696-8a95-04d0851bd551", + target_ref: "attack-pattern--82f04b1e-5371-4a6f-be06-411f0f43b483", + external_references: [], + description: "Campaign uses technique", + relationship_type: "uses", + id: "relationship--d5426745-9530-485e-a757-d8c540f600f8", + type: "relationship", + modified: "2021-06-06T14:00:00.000Z", + created: "2021-06-06T14:00:00.000Z", + spec_version: "2.1" + }, { created_by_ref: "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", object_marking_refs: [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" @@ -564,6 +647,22 @@ const initialObjectData = { modified: "2021-06-08T14:00:00.000Z", created: "2021-06-08T14:00:00.000Z", spec_version: "2.1" + }, + { + created_by_ref: "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", + object_marking_refs: [ + "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" + ], + source_ref: "campaign--649b389e-1f7a-4696-8a95-04d0851bd551", + target_ref: "intrusion-set--ed0222fb-b970-4337-b9a2-62aeb02860e5", + external_references: [], + description: "Campaign attributed to group and is the only reference to the group", + relationship_type: "attributed-to", + id: "relationship--1e1c5e5a-2a3e-423f-b1d0-67b7dc5b90cc", + type: "relationship", + modified: "2023-06-08T14:00:00.000Z", + created: "2023-06-08T14:00:00.000Z", + spec_version: "2.1" } ] }; @@ -632,7 +731,7 @@ describe('STIX Bundles Basic API', function () { // We expect to get the created collection object const collection = res.body; expect(collection).toBeDefined(); - expect(collection.workspace.import_categories.additions.length).toBe(24); + expect(collection.workspace.import_categories.additions.length).toBe(initialObjectData.objects[0].x_mitre_contents.length); expect(collection.workspace.import_categories.errors.length).toBe(0); done(); } @@ -751,9 +850,12 @@ describe('STIX Bundles Basic API', function () { const stixBundle = res.body; expect(stixBundle).toBeDefined(); expect(Array.isArray(stixBundle.objects)).toBe(true); - // 2 primary objects, 2 relationship objects, 3 secondary object, + // 3 primary objects, 5 relationship objects, 5 secondary objects, // 1 identity, 1 marking definition - expect(stixBundle.objects.length).toBe(9); + expect(stixBundle.objects.length).toBe(15); + + const groupObjects = stixBundle.objects.filter(o => o.type === 'intrusion-set'); + expect(groupObjects.length).toBe(2); done(); } diff --git a/bin/www b/bin/www index 3b9cc07e..7d92398c 100644 --- a/bin/www +++ b/bin/www @@ -87,6 +87,16 @@ async function runServer() { server.close(); }); + process.on('uncaughtException', (err, origin) => { + logger.error(`Uncaught exception: ${ err }`); + logger.error(`Exception origin: ${ origin }`); + logger.error(err.stack); + + logger.error('Terminating app after uncaught exception'); + + process.exit(1); + }); + // Wait for the server to close const events = require('events'); await events.once(server, 'close'); diff --git a/package-lock.json b/package-lock.json index 81049dba..4465cb4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "attack-workbench-rest-api", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "attack-workbench-rest-api", - "version": "2.1.0", + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { "@apidevtools/json-schema-ref-parser": "^10.1.0", @@ -16,7 +16,7 @@ "compression": "^1.7.4", "convict": "^6.2.4", "cors": "^2.8.5", - "express": "^4.18.2", + "express": "^4.19.2", "express-openapi-validator": "^4.13.8", "express-session": "^1.17.3", "helmet": "^4.6.0", @@ -2721,6 +2721,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -3277,16 +3278,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -3394,27 +3395,12 @@ } ] }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">= 0.6" } }, "node_modules/express/node_modules/on-finished": { @@ -3428,20 +3414,6 @@ "node": ">= 0.8" } }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -9091,7 +9063,8 @@ "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true }, "cookie-signature": { "version": "1.0.6", @@ -9499,16 +9472,16 @@ } }, "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -9536,24 +9509,10 @@ "vary": "~1.1.2" }, "dependencies": { - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } + "cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" }, "on-finished": { "version": "2.4.1", @@ -9563,17 +9522,6 @@ "ee-first": "1.1.1" } }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/package.json b/package.json index cfbb7806..d9f8a83f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "attack-workbench-rest-api", - "version": "2.1.0", + "version": "2.2.0", "attackSpecVersion": "3.2.0", "description": "An application allowing users to explore, create, annotate, and share extensions of the MITRE ATT&CKĀ® knowledge base. This repository contains the REST API service for storing, querying, and editing ATT&CK objects.", "keywords": [ @@ -41,7 +41,7 @@ "compression": "^1.7.4", "convict": "^6.2.4", "cors": "^2.8.5", - "express": "^4.18.2", + "express": "^4.19.2", "express-openapi-validator": "^4.13.8", "express-session": "^1.17.3", "helmet": "^4.6.0",