diff --git a/.projenrc.ts b/.projenrc.ts index ed25ff064..e8b2a2dc5 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -2,6 +2,7 @@ SPDX-License-Identifier: Apache-2.0 */ import { AwsArchProject } from "./projenrc/projects/aws-arch-project"; import { CdkGraphPluginDiagramProject } from "./projenrc/projects/cdk-graph-plugin-diagram-project"; +import { CdkGraphPluginThreatComposerProject } from "./projenrc/projects/cdk-graph-plugin-threat-composer-project"; import { CdkGraphProject } from "./projenrc/projects/cdk-graph-project"; import { CloudscapeReactTsWebsiteProject } from "./projenrc/projects/cloudscape-react-ts-website-project"; import { DocsProject } from "./projenrc/projects/docs-project"; @@ -29,6 +30,7 @@ new CloudscapeReactTsWebsiteProject(monorepoProject); new AwsArchProject(monorepoProject); new CdkGraphProject(monorepoProject); new CdkGraphPluginDiagramProject(monorepoProject); +new CdkGraphPluginThreatComposerProject(monorepoProject); new PipelineProject(monorepoProject); new InfrastructureProject(monorepoProject); diff --git a/docs/project.json b/docs/project.json index 3ca6010ef..9b228584b 100644 --- a/docs/project.json +++ b/docs/project.json @@ -76,6 +76,7 @@ "@aws/aws-arch", "@aws/cdk-graph", "@aws/cdk-graph-plugin-diagram", + "@aws/cdk-graph-plugin-threat-composer", "@aws/pipeline", "@aws/infrastructure", "@aws/docs" diff --git a/package.json b/package.json index 85803be75..43b2ee99d 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@mrgrain/jsii-struct-builder": "^0.5.20", "@pnpm/types": "^9.0.0", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "fast-xml-parser": "^4.3.2", "projen": "^0.76.25" }, @@ -100,6 +100,7 @@ "packages/aws-arch", "packages/cdk-graph", "packages/cdk-graph-plugin-diagram", + "packages/cdk-graph-plugin-threat-composer", "packages/cloudscape-react-ts-website", "docs", "packages/identity", diff --git a/packages/cdk-graph-plugin-threat-composer/.eslintrc.json b/packages/cdk-graph-plugin-threat-composer/.eslintrc.json new file mode 100644 index 000000000..6f69ddb6d --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.eslintrc.json @@ -0,0 +1,141 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen". +{ + "env": { + "jest": true, + "node": true + }, + "root": true, + "plugins": [ + "@typescript-eslint", + "import", + "prettier", + "header" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module", + "project": "./tsconfig.dev.json" + }, + "extends": [ + "plugin:import/typescript", + "prettier", + "plugin:prettier/recommended" + ], + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [ + ".ts", + ".tsx" + ] + }, + "import/resolver": { + "node": {}, + "typescript": { + "project": "./tsconfig.dev.json", + "alwaysTryTypes": true + } + } + }, + "ignorePatterns": [ + "*.js", + "*.d.ts", + "node_modules/", + "*.generated.ts", + "coverage", + "scripts/**/*.ts" + ], + "rules": { + "prettier/prettier": [ + "error" + ], + "@typescript-eslint/no-require-imports": [ + "error" + ], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": [ + "**/test/**", + "**/build-tools/**" + ], + "optionalDependencies": false, + "peerDependencies": true + } + ], + "import/no-unresolved": [ + "error" + ], + "import/order": [ + "warn", + { + "groups": [ + "builtin", + "external" + ], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + } + } + ], + "no-duplicate-imports": [ + "error" + ], + "no-shadow": [ + "off" + ], + "@typescript-eslint/no-shadow": [ + "error" + ], + "key-spacing": [ + "error" + ], + "no-multiple-empty-lines": [ + "error" + ], + "@typescript-eslint/no-floating-promises": [ + "error" + ], + "no-return-await": [ + "off" + ], + "@typescript-eslint/return-await": [ + "error" + ], + "no-trailing-spaces": [ + "error" + ], + "dot-notation": [ + "error" + ], + "no-bitwise": [ + "error" + ], + "@typescript-eslint/member-ordering": [ + "error", + { + "default": [ + "public-static-field", + "public-static-method", + "protected-static-field", + "protected-static-method", + "private-static-field", + "private-static-method", + "field", + "constructor", + "method" + ] + } + ], + "header/header": [ + 2, + "block", + [ + "! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.", + "SPDX-License-Identifier: Apache-2.0 " + ] + ] + }, + "overrides": [] +} diff --git a/packages/cdk-graph-plugin-threat-composer/.gitattributes b/packages/cdk-graph-plugin-threat-composer/.gitattributes new file mode 100644 index 000000000..ed73610ac --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.gitattributes @@ -0,0 +1,20 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen". + +/.eslintrc.json linguist-generated +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.npmignore linguist-generated +/.npmrc linguist-generated +/.prettierignore linguist-generated +/.prettierrc.json linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/docs/api linguist-generated +/LICENSE linguist-generated +/package.json linguist-generated +/pnpm-lock.yaml linguist-generated +/project.json linguist-generated +/README.md linguist-generated +/tsconfig.dev.json linguist-generated \ No newline at end of file diff --git a/packages/cdk-graph-plugin-threat-composer/.gitignore b/packages/cdk-graph-plugin-threat-composer/.gitignore new file mode 100644 index 000000000..bd67e77b2 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.gitignore @@ -0,0 +1,50 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/package.json +!/LICENSE +!/.npmignore +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +LICENSE_THIRD_PARTY +!/.projenrc.js +/test-reports/ +junit.xml +/coverage/ +!/.prettierignore +!/.prettierrc.json +!/.npmrc +!/test/ +!/tsconfig.dev.json +!/src/ +/lib +/dist/ +!/.eslintrc.json +.jsii +tsconfig.json +!/project.json +/docs/api +!/README.md diff --git a/packages/cdk-graph-plugin-threat-composer/.npmignore b/packages/cdk-graph-plugin-threat-composer/.npmignore new file mode 100644 index 000000000..e5ff9bb11 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.npmignore @@ -0,0 +1,21 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen". +/.projen/ +/test-reports/ +junit.xml +/coverage/ +/test/ +/tsconfig.dev.json +/src/ +!/lib/ +!/lib/**/*.js +!/lib/**/*.d.ts +dist +/tsconfig.json +/.github/ +/.vscode/ +/.idea/ +/.projenrc.js +tsconfig.tsbuildinfo +/.eslintrc.json +!.jsii +**/node_modules diff --git a/packages/cdk-graph-plugin-threat-composer/.prettierignore b/packages/cdk-graph-plugin-threat-composer/.prettierignore new file mode 100644 index 000000000..17fe1524d --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.prettierignore @@ -0,0 +1 @@ +# ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen". diff --git a/packages/cdk-graph-plugin-threat-composer/.prettierrc.json b/packages/cdk-graph-plugin-threat-composer/.prettierrc.json new file mode 100644 index 000000000..84c85a388 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/packages/cdk-graph-plugin-threat-composer/.projen/deps.json b/packages/cdk-graph-plugin-threat-composer/.projen/deps.json new file mode 100644 index 000000000..c04458568 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.projen/deps.json @@ -0,0 +1,178 @@ +{ + "dependencies": [ + { + "name": "@aws/aws-arch", + "version": "^0.x", + "type": "build" + }, + { + "name": "@aws/cdk-graph", + "version": "^0.x", + "type": "build" + }, + { + "name": "@aws/pdk-nag", + "version": "^0.x", + "type": "build" + }, + { + "name": "@types/jest", + "type": "build" + }, + { + "name": "@types/lodash", + "type": "build" + }, + { + "name": "@types/node", + "version": "^18", + "type": "build" + }, + { + "name": "@typescript-eslint/eslint-plugin", + "version": "^6", + "type": "build" + }, + { + "name": "@typescript-eslint/parser", + "version": "^6", + "type": "build" + }, + { + "name": "aws-cdk-lib", + "type": "build" + }, + { + "name": "cdk-nag", + "type": "build" + }, + { + "name": "constructs", + "type": "build" + }, + { + "name": "eslint-config-prettier", + "type": "build" + }, + { + "name": "eslint-import-resolver-node", + "type": "build" + }, + { + "name": "eslint-import-resolver-typescript", + "type": "build" + }, + { + "name": "eslint-plugin-header", + "type": "build" + }, + { + "name": "eslint-plugin-import", + "type": "build" + }, + { + "name": "eslint-plugin-prettier", + "type": "build" + }, + { + "name": "eslint", + "version": "^8", + "type": "build" + }, + { + "name": "fs-extra", + "type": "build" + }, + { + "name": "jest", + "type": "build" + }, + { + "name": "jest-junit", + "version": "^15", + "type": "build" + }, + { + "name": "jsii", + "type": "build" + }, + { + "name": "jsii-diff", + "type": "build" + }, + { + "name": "jsii-docgen", + "type": "build" + }, + { + "name": "jsii-pacmak", + "type": "build" + }, + { + "name": "jsii-rosetta", + "type": "build" + }, + { + "name": "prettier", + "type": "build" + }, + { + "name": "projen", + "type": "build" + }, + { + "name": "ts-jest", + "type": "build" + }, + { + "name": "typescript", + "type": "build" + }, + { + "name": "lodash", + "type": "bundled" + }, + { + "name": "@babel/traverse", + "version": "7.23.2", + "type": "override" + }, + { + "name": "tar", + "version": "^4.4.18", + "type": "override" + }, + { + "name": "@aws/aws-arch", + "version": "^0.x", + "type": "peer" + }, + { + "name": "@aws/cdk-graph", + "version": "^0.x", + "type": "peer" + }, + { + "name": "@aws/pdk-nag", + "version": "^0.x", + "type": "peer" + }, + { + "name": "aws-cdk-lib", + "type": "peer" + }, + { + "name": "cdk-nag", + "type": "peer" + }, + { + "name": "constructs", + "type": "peer" + }, + { + "name": "projen", + "type": "peer" + } + ], + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\"." +} diff --git a/packages/cdk-graph-plugin-threat-composer/.projen/files.json b/packages/cdk-graph-plugin-threat-composer/.projen/files.json new file mode 100644 index 000000000..026057b8c --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.projen/files.json @@ -0,0 +1,17 @@ +{ + "files": [ + ".eslintrc.json", + ".gitattributes", + ".gitignore", + ".prettierignore", + ".prettierrc.json", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "LICENSE", + "project.json", + "README.md", + "tsconfig.dev.json" + ], + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\"." +} diff --git a/packages/cdk-graph-plugin-threat-composer/.projen/tasks.json b/packages/cdk-graph-plugin-threat-composer/.projen/tasks.json new file mode 100644 index 000000000..36f992335 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/.projen/tasks.json @@ -0,0 +1,195 @@ +{ + "tasks": { + "build": { + "name": "build", + "description": "Full release build", + "steps": [ + { + "spawn": "pre-compile" + }, + { + "spawn": "compile" + }, + { + "spawn": "post-compile" + }, + { + "spawn": "test" + }, + { + "spawn": "package" + } + ] + }, + "compat": { + "name": "compat", + "description": "Perform API compatibility check against latest version", + "steps": [ + { + "exec": "jsii-diff npm:$(node -p \"require('./package.json').name\") -k --ignore-file .compatignore || (echo \"\nUNEXPECTED BREAKING CHANGES: add keys such as 'removed:constructs.Node.of' to .compatignore to skip.\n\" && exit 1)" + } + ] + }, + "compile": { + "name": "compile", + "description": "Only compile", + "steps": [ + { + "exec": "jsii --silence-warnings=reserved-word" + } + ] + }, + "default": { + "name": "default", + "description": "Synthesize project files" + }, + "docgen": { + "name": "docgen", + "description": "Generate API docs from .jsii manifest", + "steps": [ + { + "exec": "mkdir -p docs/api/typescript && jsii-docgen -r=false -o docs/api/typescript/index.md && sed -i'' -e 's/@aws\\//@aws\\/pdk\\//g' docs/api/typescript/index.md" + }, + { + "exec": "mkdir -p docs/api/python && jsii-docgen -l python -r=false -o docs/api/python/index.md && sed -i'' -e 's/aws.pdk/aws.pdk.cdk_graph_plugin_threat_composer/g' docs/api/python/index.md" + }, + { + "exec": "mkdir -p docs/api/java && jsii-docgen -l java -r=false -o docs/api/java/index.md && sed -i'' -e 's/software.aws.pdk/software.aws.pdk.cdk_graph_plugin_threat_composer/g' docs/api/java/index.md" + } + ] + }, + "eslint": { + "name": "eslint", + "description": "Runs eslint against the codebase", + "steps": [ + { + "exec": "eslint --ext .ts,.tsx ${CI:-'--fix'} --no-error-on-unmatched-pattern src test", + "receiveArgs": true + } + ] + }, + "eslint-staged": { + "name": "eslint-staged", + "description": "Run eslint against the staged files only", + "steps": [ + { + "exec": "eslint --fix --no-error-on-unmatched-pattern $(git diff --name-only --relative --staged HEAD . | grep -E '.(ts|tsx)$' | grep -v 'samples/*' | xargs)" + } + ] + }, + "install": { + "name": "install", + "description": "Install project dependencies and update lockfile (non-frozen)", + "steps": [ + { + "exec": "pnpm i --no-frozen-lockfile" + } + ] + }, + "install:ci": { + "name": "install:ci", + "description": "Install project dependencies using frozen lockfile", + "steps": [ + { + "exec": "pnpm i --frozen-lockfile" + } + ] + }, + "jest": { + "name": "jest", + "steps": [ + { + "exec": "jest --passWithNoTests ${CI:-'--updateSnapshot'} ${NX_WORKSPACE_ROOT:+'--runInBand'}", + "receiveArgs": true + } + ] + }, + "package": { + "name": "package", + "description": "Creates the distribution package", + "steps": [ + { + "exec": "monorepo.pnpm-link-bundled-transitive-deps packages/cdk-graph-plugin-threat-composer" + }, + { + "spawn": "eslint" + } + ] + }, + "package-all": { + "name": "package-all", + "description": "Packages artifacts for all target languages" + }, + "package:java": { + "name": "package:java", + "description": "Create java language bindings", + "steps": [ + { + "exec": "jsii-pacmak -v --target java --pack-command='pnpm pack'" + } + ] + }, + "package:python": { + "name": "package:python", + "description": "Create python language bindings", + "steps": [ + { + "exec": "jsii-pacmak -v --target python --pack-command='pnpm pack'" + } + ] + }, + "post-compile": { + "name": "post-compile", + "description": "Runs after successful compilation", + "steps": [ + { + "exec": "rm -f tsconfig.json" + }, + { + "spawn": "docgen" + } + ] + }, + "pre-compile": { + "name": "pre-compile", + "description": "Prepare the project for compilation", + "steps": [ + { + "exec": "rm -f tsconfig.json" + } + ] + }, + "test": { + "name": "test", + "description": "Run tests", + "steps": [ + { + "spawn": "jest" + } + ] + }, + "test:watch": { + "name": "test:watch", + "description": "Run jest in watch mode", + "steps": [ + { + "exec": "jest --watch" + } + ] + }, + "watch": { + "name": "watch", + "description": "Watch & compile in the background", + "steps": [ + { + "exec": "jsii -w --silence-warnings=reserved-word" + } + ] + } + }, + "env": { + "PATH": "$(pnpm -c exec \"node --print process.env.PATH\")", + "JSII_SUPPRESS_UPGRADE_PROMPT": "true" + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\"." +} diff --git a/packages/cdk-graph-plugin-threat-composer/LICENSE b/packages/cdk-graph-plugin-threat-composer/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/cdk-graph-plugin-threat-composer/README.md b/packages/cdk-graph-plugin-threat-composer/README.md new file mode 100644 index 000000000..a7ae8e5d1 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/README.md @@ -0,0 +1,3 @@ +# cdk-graph-plugin-threat-composer + +Please refer to [Developer Guide](./docs/developer_guides/cdk-graph-plugin-threat-composer/index.md). \ No newline at end of file diff --git a/packages/cdk-graph-plugin-threat-composer/docs/assets/cdk-graph-plugin-threat-composer/threat-composer-screenshot.png b/packages/cdk-graph-plugin-threat-composer/docs/assets/cdk-graph-plugin-threat-composer/threat-composer-screenshot.png new file mode 100644 index 000000000..27a048883 Binary files /dev/null and b/packages/cdk-graph-plugin-threat-composer/docs/assets/cdk-graph-plugin-threat-composer/threat-composer-screenshot.png differ diff --git a/packages/cdk-graph-plugin-threat-composer/docs/developer_guides/cdk-graph-plugin-threat-composer/index.md b/packages/cdk-graph-plugin-threat-composer/docs/developer_guides/cdk-graph-plugin-threat-composer/index.md new file mode 100644 index 000000000..8dc615ebf --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/docs/developer_guides/cdk-graph-plugin-threat-composer/index.md @@ -0,0 +1,78 @@ +# Cdk Graph Threat Composer Plugin + +![experimental](https://img.shields.io/badge/stability-experimental-orange.svg) +[![API Documentation](https://img.shields.io/badge/view-API_Documentation-blue.svg)](../../api/typescript/cdk-graph-plugin-threat-composer/index.md) +[![Source Code](https://img.shields.io/badge/view-Source_Code-blue.svg)](https://github.com/aws/aws-pdk/tree/mainline/packages/cdk-graph-plugin-threat-composer) + +> This plugin generates [Threat Composer](https://github.com/awslabs/threat-composer) threat models, utilizing the [cdk-graph](https://aws.github.io/aws-pdk/typescript/cdk-graph/index.html) framework. + +![threat-composer](../../assets/cdk-graph-plugin-threat-composer/threat-composer-screenshot.png) + +### Quick Start + +```ts +// bin/app.ts + +// Must wrap cdk app with async IIFE function to enable async cdk-graph report +(async () => { + const app = PDKNag.app(); + // ... add stacks, etc + const graph = new CdkGraph(app, { + plugins: [ + // Configure the plugin + new CdkGraphThreatComposerPlugin({ + applicationDetails: { + name: "My Application" + }, + }), + ], + }); + + app.synth(); + + // async cdk-graph reporting hook + await graph.report(); +})(); + +// => cdk.out/cdkgraph/threat-model.tc.json +``` + +!!!warning + This plugin must be used in tandem with [pdk-nag](../../developer_guides/pdk-nag/index.md), using `PDKNag.app()` + +> This plugin currently only supports `async report()` generation following the above example. **Make sure to wrap the cdk app with _async IIFE_.** + +### How it Works + +This plugin uses the [CDK Nag](https://github.com/cdklabs/cdk-nag) findings from your [pdk-nag](../../developer_guides/pdk-nag/index.md) app to generate a starter [Threat Composer](https://github.com/awslabs/threat-composer) threat model for you. + +Upon configuring the plugin and synthesizing CDK, you'll find a `cdk.out/cdkgraph/threat-composer.tc.json` file in your project. You can import this into the [Threat Composer](https://awslabs.github.io/threat-composer/) tool to view and edit your threat model. + +!!!note + The generated threat model is not complete, however it provides a good starting point for you to consider possible threats to your application and how they are mitigated. + + After editing your threat model, it's recommended that you manage it as part of your codebase by checking it into version control. + +This plugin generates the threat model based on a hand-crafted mapping of CDK Nag rules to the threats which they intend to mitigate. + +### Architecture Diagram + +Specify this plugin after the [CDK Graph Diagram Plugin](../../developer_guides/cdk-graph-plugin-diagram/index.md) to automatically include a generated architecture diagram in your threat model. + +```ts +(async () => { + const app = PDKNag.app(); + // ... add stacks, etc + const graph = new CdkGraph(app, { + plugins: [ + new CdkGraphDiagramPlugin(), + // Configure the plugin after the cdk graph diagram plugin + new CdkGraphThreatComposerPlugin(), + ], + }); + + app.synth(); + + await graph.report(); +})(); +``` diff --git a/packages/cdk-graph-plugin-threat-composer/package.json b/packages/cdk-graph-plugin-threat-composer/package.json new file mode 100644 index 000000000..b87dcfe9d --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/package.json @@ -0,0 +1,157 @@ +{ + "name": "@aws/cdk-graph-plugin-threat-composer", + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-pdk" + }, + "scripts": { + "build": "pnpm exec projen build", + "compat": "pnpm exec projen compat", + "compile": "pnpm exec projen compile", + "default": "pnpm exec projen default", + "docgen": "pnpm exec projen docgen", + "eslint": "pnpm exec projen eslint", + "eslint-staged": "pnpm exec projen eslint-staged", + "jest": "pnpm exec projen jest", + "package": "pnpm exec projen package", + "package-all": "pnpm exec projen package-all", + "package:java": "pnpm exec projen package:java", + "package:python": "pnpm exec projen package:python", + "post-compile": "pnpm exec projen post-compile", + "pre-compile": "pnpm exec projen pre-compile", + "test": "pnpm exec projen test", + "test:watch": "pnpm exec projen test:watch", + "watch": "pnpm exec projen watch" + }, + "author": { + "name": "AWS APJ COPE", + "email": "apj-cope@amazon.com", + "organization": false + }, + "devDependencies": { + "@aws/aws-arch": "0.0.0", + "@aws/cdk-graph": "0.0.0", + "@aws/pdk-nag": "0.0.0", + "@types/jest": "^29.5.7", + "@types/lodash": "^4.14.200", + "@types/node": "^18", + "@typescript-eslint/eslint-plugin": "^6", + "@typescript-eslint/parser": "^6", + "aws-cdk-lib": "2.104.0", + "cdk-nag": "2.28.2", + "constructs": "10.3.0", + "eslint": "^8", + "eslint-config-prettier": "^8.10.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-header": "^3.1.1", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^4.2.1", + "fs-extra": "^11.1.1", + "jest": "^29.7.0", + "jest-junit": "^15", + "jsii": "^5.2.24", + "jsii-diff": "^1.91.0", + "jsii-docgen": "^8.0.56", + "jsii-pacmak": "^1.91.0", + "jsii-rosetta": "^1.91.0", + "prettier": "^2.8.8", + "projen": "0.76.25", + "ts-jest": "^29.1.1", + "typescript": "^5.2.2" + }, + "peerDependencies": { + "@aws/aws-arch": "^0.x", + "@aws/cdk-graph": "^0.x", + "@aws/pdk-nag": "^0.x", + "aws-cdk-lib": "^2.104.0", + "cdk-nag": "^2.28.2", + "constructs": "^10.3.0", + "projen": "^0.76.25" + }, + "dependencies": { + "lodash": "^4.17.21" + }, + "bundledDependencies": [ + "lodash" + ], + "keywords": [ + "aws", + "cdk", + "cdk-graph", + "cdk-graph-plugin", + "graph", + "jsii", + "pdk", + "projen" + ], + "main": "lib/index.js", + "license": "Apache-2.0", + "version": "0.0.0", + "jest": { + "testMatch": [ + "/src/**/__tests__/**/*.ts?(x)", + "/(test|src)/**/*(*.)@(spec|test).ts?(x)" + ], + "clearMocks": true, + "collectCoverage": true, + "coverageReporters": [ + "json", + "lcov", + "clover", + "cobertura", + "text" + ], + "coverageDirectory": "coverage", + "coveragePathIgnorePatterns": [ + "/node_modules/", + "/\\.tmp/" + ], + "testPathIgnorePatterns": [ + "/node_modules/", + "/\\.tmp/" + ], + "watchPathIgnorePatterns": [ + "/node_modules/", + "/\\.tmp/" + ], + "reporters": [ + "default", + [ + "jest-junit", + { + "outputDirectory": "test-reports" + } + ] + ], + "preset": "ts-jest", + "globals": { + "ts-jest": { + "tsconfig": "tsconfig.dev.json" + } + } + }, + "types": "lib/index.d.ts", + "stability": "experimental", + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.aws.pdk", + "maven": { + "groupId": "software.aws", + "artifactId": "pdk" + } + }, + "python": { + "distName": "aws_pdk", + "module": "aws_pdk" + } + }, + "tsc": { + "outDir": "lib", + "rootDir": "src" + } + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\"." +} diff --git a/packages/cdk-graph-plugin-threat-composer/project.json b/packages/cdk-graph-plugin-threat-composer/project.json new file mode 100644 index 000000000..c7661276f --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/project.json @@ -0,0 +1,147 @@ +{ + "name": "@aws/cdk-graph-plugin-threat-composer", + "root": "packages/cdk-graph-plugin-threat-composer", + "targets": { + "build": { + "inputs": [ + "default", + "^default", + "!{projectRoot}/.jsii", + "!{projectRoot}/lib/**/*", + "!{projectRoot}/dist/**/*", + "!{projectRoot}/coverage/**/*", + "!{projectRoot}/test-reports/**/*", + "!{projectRoot}/docs/api/**/*" + ], + "outputs": [ + "{projectRoot}/.jsii", + "{projectRoot}/lib", + "{projectRoot}/dist", + "{projectRoot}/coverage", + "{projectRoot}/test-reports", + "{projectRoot}/docs/api" + ], + "dependsOn": [ + "^build" + ], + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen build", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "default": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen default", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "pre-compile": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen pre-compile", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "compile": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen compile", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "post-compile": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen post-compile", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "test": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen test", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "package": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen package", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "test:watch": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen test:watch", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "watch": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen watch", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "eslint": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen eslint", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "compat": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen compat", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "package-all": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen package-all", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "package:java": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen package:java", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "package:python": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen package:python", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "eslint-staged": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen eslint-staged", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "jest": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen jest", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + }, + "docgen": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm exec projen docgen", + "cwd": "packages/cdk-graph-plugin-threat-composer" + } + } + }, + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\"." +} diff --git a/packages/cdk-graph-plugin-threat-composer/src/index.ts b/packages/cdk-graph-plugin-threat-composer/src/index.ts new file mode 100644 index 000000000..ab6a65957 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/src/index.ts @@ -0,0 +1,4 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +export * from "./plugin"; +export * from "./model-generator/types"; diff --git a/packages/cdk-graph-plugin-threat-composer/src/model-generator/base-model/README.md b/packages/cdk-graph-plugin-threat-composer/src/model-generator/base-model/README.md new file mode 100644 index 000000000..4ec33bcb0 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/src/model-generator/base-model/README.md @@ -0,0 +1,9 @@ +## Modifying the Base Threat Model + +This folder contains a base threat model (`.tc.json` file) with example threats mapped to CDK Nag rules, and the plugin filters to only the applicable threats to the CDK project. + +The easiest way to modify the threat model is to import the json file into the [Threat Composer](https://awslabs.github.io/threat-composer/) tool, modify it using the UI, and then export it as json and replace the contents in this repository. + +Note that CDK Nag rules are treated as "Mitigations" in Threat Composer, and the content for the mitigation must be of the format `cdk-nag rule: `. + +The CDK Nag rules can be found [here](https://github.com/cdklabs/cdk-nag/tree/main/src/rules), where the rule name is the file name of a given rule file without the extension, eg `IAMNoManagedPolicies` for [iam/IAMNoManagedPolicies.ts](https://github.com/cdklabs/cdk-nag/blob/main/src/rules/iam/IAMNoManagedPolicies.ts). diff --git a/packages/cdk-graph-plugin-threat-composer/src/model-generator/base-model/threat-composer-base-model.tc.json b/packages/cdk-graph-plugin-threat-composer/src/model-generator/base-model/threat-composer-base-model.tc.json new file mode 100644 index 000000000..ee7664808 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/src/model-generator/base-model/threat-composer-base-model.tc.json @@ -0,0 +1,3171 @@ +{ + "schema": 1, + "applicationInfo": { + "name": "My Application", + "description": "**Important**: This threat model is not comprehensive or complete. This document does not list all possible threats, and where threats do have mapped mitigations - these mitigations are not deemed to be complete.\n\nConsider this as a starting point for your own diligence and threat modeling." + }, + "architecture": { + "image": "", + "description": "" + }, + "dataflow": { + "image": "", + "description": "**Note:** A data flow diagram has not been captured at this stage. You should consider creating a data-flow diagram." + }, + "assumptions": [], + "mitigations": [ + { + "id": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "numericId": 107, + "displayOrder": 107, + "tags": [ + "VPC" + ], + "content": "cdk-nag rule: VPCSubnetAutoAssignPublicIpDisabled" + }, + { + "id": "b77f601d-822e-4911-b1da-6756ba7d4527", + "numericId": 106, + "displayOrder": 106, + "tags": [ + "VPC" + ], + "content": "cdk-nag rule: VPCNoNACLs" + }, + { + "id": "be57de80-6cb4-420d-80bc-c7fb6a97d6ea", + "numericId": 105, + "displayOrder": 105, + "tags": [ + "Timestream" + ], + "content": "cdk-nag rule: TimestreamDatabaseCustomerManagedKey" + }, + { + "id": "a92c9799-aba4-45f9-a639-8c922d7706d0", + "numericId": 104, + "displayOrder": 104, + "tags": [ + "SQS" + ], + "content": "cdk-nag rule: SQSQueueSSLRequestsOnly" + }, + { + "id": "a1aae9d0-1511-4f93-841e-801e9b47976f", + "numericId": 103, + "displayOrder": 103, + "tags": [ + "SQS" + ], + "content": "cdk-nag rule: SQSQueueSSE" + }, + { + "id": "7e9478e3-4571-4c36-bb7c-bb33acf4ec08", + "numericId": 102, + "displayOrder": 102, + "tags": [ + "SNS" + ], + "content": "cdk-nag rule: SNSTopicSSLPublishOnly" + }, + { + "id": "35eefa29-d011-4b50-a7a8-a204a2b01b34", + "numericId": 101, + "displayOrder": 101, + "tags": [ + "SNS" + ], + "content": "cdk-nag rule: SNSEncryptedKMS" + }, + { + "id": "fff9fac4-1512-4a49-81a3-88e420f6c110", + "numericId": 100, + "displayOrder": 100, + "tags": [ + "Secrets Manager" + ], + "content": "cdk-nag rule: SecretsManagerRotationEnabled" + }, + { + "id": "d23b82f2-f274-42eb-9edd-75ddc0ca75d2", + "numericId": 99, + "displayOrder": 99, + "tags": [ + "SageMaker" + ], + "content": "cdk-nag rule: SageMakerNotebookNoDirectInternetAccess" + }, + { + "id": "75327602-a8f0-48ed-b635-305678ef5893", + "numericId": 98, + "displayOrder": 98, + "tags": [ + "SageMaker" + ], + "content": "cdk-nag rule: SageMakerNotebookInVPC" + }, + { + "id": "b6cfe99f-842f-4567-8611-92c7cea45eb2", + "numericId": 97, + "displayOrder": 97, + "tags": [ + "SageMaker" + ], + "content": "cdk-nag rule: SageMakerNotebookInstanceKMSKeyConfigured" + }, + { + "id": "c0f8d761-b616-49d4-b60e-d9d413c91f19", + "numericId": 96, + "displayOrder": 96, + "tags": [ + "S3", + "CloudFront" + ], + "content": "cdk-nag rule: S3WebBucketOAIAccess" + }, + { + "id": "b19fd780-64a3-42c6-a0d2-92833af17e40", + "numericId": 95, + "displayOrder": 95, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketSSLRequestsOnly" + }, + { + "id": "1483c264-8b13-4954-8e79-97bb63163b57", + "numericId": 94, + "displayOrder": 94, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketPublicWriteProhibited" + }, + { + "id": "c4b91bbd-8e0f-457e-97e1-3b940b2007ef", + "numericId": 93, + "displayOrder": 93, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketPublicReadProhibited" + }, + { + "id": "646feb9c-6f18-4307-8a90-8a44b851d176", + "numericId": 92, + "displayOrder": 92, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketLoggingEnabled" + }, + { + "id": "0ae5ca12-88c7-4648-a1e8-28ad585c3336", + "numericId": 91, + "displayOrder": 91, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketLevelPublicAccessProhibited" + }, + { + "id": "78d761ef-4297-45d1-ae1b-7ba545d39130", + "numericId": 90, + "displayOrder": 90, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftRequireTlsSSL" + }, + { + "id": "232d24ee-cfd5-4351-bd5d-3dfdcf2508ee", + "numericId": 89, + "displayOrder": 89, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftClusterVersionUpgrade" + }, + { + "id": "46e8c83a-a4d0-428d-ba9e-b4c9e68bbc24", + "numericId": 88, + "displayOrder": 88, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftClusterPublicAccess" + }, + { + "id": "b08bdd06-48c1-4c3f-8401-464d667e92e0", + "numericId": 87, + "displayOrder": 87, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftClusterNonDefaultUsername" + }, + { + "id": "857bbf82-30f5-40f0-9ffd-60b6b67053e9", + "numericId": 86, + "displayOrder": 86, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftClusterNonDefaultPort" + }, + { + "id": "c75b2076-9a00-4808-8525-a25d629fb784", + "numericId": 85, + "displayOrder": 85, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftClusterInVPC" + }, + { + "id": "55c0cdfd-c8e5-4d41-a700-de7a89557782", + "numericId": 84, + "displayOrder": 84, + "tags": [ + "Redshift" + ], + "content": "cdk-nag rule: RedshiftClusterEncryptionAtRest" + }, + { + "id": "de0b05cd-ff7d-4993-81c5-5bc5585151a4", + "numericId": 83, + "displayOrder": 83, + "tags": [ + "RDS" + ], + "content": "cdk-nag rule: RDSStorageEncrypted" + }, + { + "id": "59a9c68e-b899-4dea-b326-ebebda148f00", + "numericId": 82, + "displayOrder": 82, + "tags": [ + "RDS" + ], + "content": "cdk-nag rule: RDSRestrictedInbound" + }, + { + "id": "5382b34e-1cee-4fe4-acab-1e1ef283437d", + "numericId": 81, + "displayOrder": 81, + "tags": [ + "RDS" + ], + "content": "cdk-nag rule: RDSNonDefaultPort" + }, + { + "id": "dc7ad88b-55b0-480d-9023-b9ac660b388e", + "numericId": 80, + "displayOrder": 80, + "tags": [ + "RDS" + ], + "content": "cdk-nag rule: RDSInstancePublicAccess" + }, + { + "id": "cdfb2f22-d096-468c-ae64-c8a63e6d03d5", + "numericId": 79, + "displayOrder": 79, + "tags": [ + "RDS" + ], + "content": "cdk-nag rule: RDSAutomaticMinorVersionUpgradeEnabled" + }, + { + "id": "16a9eba9-5e70-4d94-b9d9-d77cf17c522f", + "numericId": 78, + "displayOrder": 78, + "tags": [ + "RDS" + ], + "content": "cdk-nag rule: AuroraMySQLPostgresIAMAuth" + }, + { + "id": "4f2ac79c-f343-4916-9b8c-b078544f81a5", + "numericId": 77, + "displayOrder": 77, + "tags": [ + "Quicksight" + ], + "content": "cdk-nag rule: QuicksightSSLConnections" + }, + { + "id": "e1239e2d-9267-4608-ab0d-09d4eab63d7d", + "numericId": 76, + "displayOrder": 76, + "tags": [ + "OpenSearch" + ], + "content": "cdk-nag rule: OpenSearchNoUnsignedOrAnonymousAccess" + }, + { + "id": "68089d75-7a9f-4a48-b742-95dde35b069a", + "numericId": 75, + "displayOrder": 75, + "tags": [ + "OpenSearch" + ], + "content": "cdk-nag rule: OpenSearchNodeToNodeEncryption" + }, + { + "id": "972fb272-b77f-4f32-95f0-bb47023d3770", + "numericId": 74, + "displayOrder": 74, + "tags": [ + "OpenSearch" + ], + "content": "cdk-nag rule: OpenSearchInVPCOnly" + }, + { + "id": "28b7cc4b-21f3-4155-a4e3-4f3dcb5e9117", + "numericId": 73, + "displayOrder": 73, + "tags": [ + "OpenSearch" + ], + "content": "cdk-nag rule: OpenSearchEncryptedAtRest" + }, + { + "id": "6288512e-5ebc-433e-bef5-a3f038119b69", + "numericId": 72, + "displayOrder": 72, + "tags": [ + "OpenSearch" + ], + "content": "cdk-nag rule: OpenSearchAllowlistedIPs" + }, + { + "id": "c22f8d36-4546-4e39-9eea-156fbbc7d99b", + "numericId": 71, + "displayOrder": 71, + "tags": [ + "Neptune" + ], + "content": "cdk-nag rule: NeptuneClusterIAMAuth" + }, + { + "id": "8912a402-b365-4d39-ab63-321825adbd1e", + "numericId": 70, + "displayOrder": 70, + "tags": [ + "Neptune" + ], + "content": "cdk-nag rule: NeptuneClusterEncryptionAtRest" + }, + { + "id": "7f0815f2-c84e-4cd9-9859-3ed693729cab", + "numericId": 69, + "displayOrder": 69, + "tags": [ + "Neptune" + ], + "content": "cdk-nag rule: NeptuneClusterAutomaticMinorVersionUpgrade" + }, + { + "id": "8f608620-f1a1-40e8-b34b-f6ea547fe0fa", + "numericId": 68, + "displayOrder": 68, + "tags": [ + "MSK" + ], + "content": "cdk-nag rule: MSKClientToBrokerTLS" + }, + { + "id": "5e01f259-e40f-460e-a1a6-0666398a2c7a", + "numericId": 67, + "displayOrder": 67, + "tags": [ + "MediaStore" + ], + "content": "cdk-nag rule: MediaStoreContainerHasContainerPolicy" + }, + { + "id": "00dc16be-7bce-4b82-830d-b3ac223a4fbf", + "numericId": 66, + "displayOrder": 66, + "tags": [ + "MediaStore" + ], + "content": "cdk-nag rule: MediaStoreContainerSSLRequestsOnly" + }, + { + "id": "4487d987-db5b-4a81-a6cb-ab736509ae2e", + "numericId": 65, + "displayOrder": 65, + "tags": [ + "MediaStore" + ], + "content": "cdk-nag rule: MediaStoreContainerCORSPolicy" + }, + { + "id": "fcd9742a-30eb-4303-97e7-206e4a1f63fd", + "numericId": 64, + "displayOrder": 64, + "tags": [ + "Lambda" + ], + "content": "cdk-nag rule: LambdaLatestVersion" + }, + { + "id": "d0d6e348-0ed5-4465-b275-ba4f301097e1", + "numericId": 63, + "displayOrder": 63, + "tags": [ + "Lambda" + ], + "content": "cdk-nag rule: LambdaFunctionUrlAuth" + }, + { + "id": "9cd8dfd8-8f1f-4697-aa2d-17378c3eb587", + "numericId": 62, + "displayOrder": 62, + "tags": [ + "KMS" + ], + "content": "cdk-nag rule: KMSBackingKeyRotationEnabled" + }, + { + "id": "c22a535f-d743-40ba-8531-e979c1235cb7", + "numericId": 61, + "displayOrder": 61, + "tags": [ + "Kinesis" + ], + "content": "cdk-nag rule: KinesisDataStreamSSE" + }, + { + "id": "a66e5b68-509d-47bd-888c-a43e390ecd82", + "numericId": 60, + "displayOrder": 60, + "tags": [ + "Kinesis" + ], + "content": "cdk-nag rule: KinesisDataStreamDefaultKeyWhenSSE" + }, + { + "id": "f1601e79-56fe-4863-8466-7d383ed65274", + "numericId": 59, + "displayOrder": 59, + "tags": [ + "Kinesis" + ], + "content": "cdk-nag rule: KinesisDataFirehoseSSE" + }, + { + "id": "4fe4bbaf-08fa-437d-b5ea-1e010610133b", + "numericId": 58, + "displayOrder": 58, + "tags": [ + "IAM" + ], + "content": "cdk-nag rule: IAMPolicyNoStatementsWithFullAccess" + }, + { + "id": "1a74ef32-b240-4173-9f02-0e8ebbc20191", + "numericId": 57, + "displayOrder": 57, + "tags": [ + "IAM" + ], + "content": "cdk-nag rule: IAMPolicyNoStatementsWithAdminAccess" + }, + { + "id": "ca417660-79a6-4725-b498-7406ffc8a9f5", + "numericId": 56, + "displayOrder": 56, + "tags": [ + "IAM" + ], + "content": "cdk-nag rule: IAMNoWildcardPermissions" + }, + { + "id": "da85ab97-eb06-4c15-9782-5a7a1924c7d4", + "numericId": 55, + "displayOrder": 55, + "tags": [ + "IAM" + ], + "content": "cdk-nag rule: IAMNoManagedPolicies" + }, + { + "id": "0ba2992b-2d77-4864-b58b-f52bacdc4349", + "numericId": 53, + "displayOrder": 53, + "tags": [ + "Glue" + ], + "content": "cdk-nag rule: GlueJobBookmarkEncrypted" + }, + { + "id": "06342334-a5c7-45f5-9325-6c8bb097f005", + "numericId": 52, + "displayOrder": 52, + "tags": [ + "Glue" + ], + "content": "cdk-nag rule: GlueEncryptedCloudWatchLogs" + }, + { + "id": "a19bfb5e-6416-49d5-ad97-48476a92921f", + "numericId": 51, + "displayOrder": 51, + "tags": [ + "Event Bridge" + ], + "content": "cdk-nag rule: EventBusOpenAccess" + }, + { + "id": "ca237931-d8f4-487a-9cf3-72d81b7107ab", + "numericId": 50, + "displayOrder": 50, + "tags": [ + "EMR" + ], + "content": "cdk-nag rule: EMRLocalDiskEncryption" + }, + { + "id": "38e3b1ce-484a-4e02-a00c-cd46686fd3ba", + "numericId": 49, + "displayOrder": 49, + "tags": [ + "EMR" + ], + "content": "cdk-nag rule: EMREncryptionInTransit" + }, + { + "id": "c8503353-a75f-4e28-a156-4424f9a28c76", + "numericId": 48, + "displayOrder": 48, + "tags": [ + "EMR" + ], + "content": "cdk-nag rule: EMRAuthEC2KeyPairOrKerberos" + }, + { + "id": "c90a9a7a-1536-4dc3-a582-3eb0abaddd8b", + "numericId": 47, + "displayOrder": 47, + "tags": [ + "ALB" + ], + "content": "cdk-nag rule: ALBHttpToHttpsRedirection" + }, + { + "id": "01867f64-62e3-4981-a571-07c42ce35dfd", + "numericId": 46, + "displayOrder": 46, + "tags": [ + "Elastic Beanstalk" + ], + "content": "cdk-nag rule: ElasticBeanstalkVPCSpecified" + }, + { + "id": "0c99176f-071d-4e9a-97d7-90fe9a7f1293", + "numericId": 45, + "displayOrder": 45, + "tags": [ + "Elastic Beanstalk" + ], + "content": "cdk-nag rule: ElasticBeanstalkManagedUpdatesEnabled" + }, + { + "id": "6a6b668e-63f1-4bd5-bfd3-dbcaf5386a69", + "numericId": 44, + "displayOrder": 44, + "tags": [ + "Elastic Beanstalk" + ], + "content": "cdk-nag rule: ElasticBeanstalkEC2InstanceLogsToS3" + }, + { + "id": "98e3e1a6-7548-405d-a896-abbda186e920", + "numericId": 43, + "displayOrder": 43, + "tags": [ + "ElastiCache" + ], + "content": "cdk-nag rule: ElastiCacheRedisClusterRedisAuth" + }, + { + "id": "f2e8e52c-3b0f-4256-9497-d2f6743971c7", + "numericId": 42, + "displayOrder": 42, + "tags": [ + "ElastiCache" + ], + "content": "cdk-nag rule: ElastiCacheRedisClusterEncryption" + }, + { + "id": "7fde0f89-ef45-49ec-a88d-3a8f17aa9a8a", + "numericId": 41, + "displayOrder": 41, + "tags": [ + "ElastiCache" + ], + "content": "cdk-nag rule: ElastiCacheClusterNonDefaultPort" + }, + { + "id": "2202a747-7921-4fff-94ec-24467b86bb55", + "numericId": 40, + "displayOrder": 40, + "tags": [ + "ElastiCache" + ], + "content": "cdk-nag rule: ElastiCacheClusterInVPC" + }, + { + "id": "c00d5353-11bb-48b0-9abd-4ac291dd4cb3", + "numericId": 39, + "displayOrder": 39, + "tags": [ + "EKS" + ], + "content": "cdk-nag rule: EKSClusterNoEndpointPublicAccess" + }, + { + "id": "24f0ecef-8c8b-4d53-b5ad-be63739587fa", + "numericId": 38, + "displayOrder": 38, + "tags": [ + "API Gateway" + ], + "content": "cdk-nag rule: APIGWRequestValidation" + }, + { + "id": "22982dbd-4fd5-47fc-804c-03f88e4f479f", + "numericId": 37, + "displayOrder": 37, + "tags": [ + "EKS" + ], + "content": "cdk-nag rule: EKSClusterControlPlaneLogs" + }, + { + "id": "0c4211b1-4bd1-464d-846e-82353ed1ebfa", + "numericId": 36, + "displayOrder": 36, + "tags": [ + "EFS" + ], + "content": "cdk-nag rule: EFSEncrypted" + }, + { + "id": "fba0d1b6-ea6e-46cb-85c8-01f0244b1d66", + "numericId": 35, + "displayOrder": 35, + "tags": [ + "ECS" + ], + "content": "cdk-nag rule: ECSTaskDefinitionNoEnvironmentVariables" + }, + { + "id": "7df3fa44-ac61-44f4-acd5-9ab2b78f2d98", + "numericId": 34, + "displayOrder": 34, + "tags": [ + "ECS" + ], + "content": "cdk-nag rule: ECSTaskDefinitionContainerLogging" + }, + { + "id": "30b62ffd-ce1e-423c-a715-458971016ced", + "numericId": 33, + "displayOrder": 33, + "tags": [ + "ECR" + ], + "content": "cdk-nag rule: ECROpenAccess" + }, + { + "id": "a3adc4bc-12e6-4e51-9a3b-f70173626aed", + "numericId": 32, + "displayOrder": 32, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2SecurityGroupDescription" + }, + { + "id": "c09ffb80-6a08-4d17-b497-6fadcf3f723e", + "numericId": 31, + "displayOrder": 31, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2RestrictedSSH" + }, + { + "id": "0edef48e-478a-4354-afba-04cbd8a678af", + "numericId": 30, + "displayOrder": 30, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2RestrictedInbound" + }, + { + "id": "dec3b995-d1ed-4a35-a3f3-b4053f05b3ab", + "numericId": 29, + "displayOrder": 29, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2RestrictedCommonPorts" + }, + { + "id": "1232e7b6-14d3-49a2-b323-cd7b789918ed", + "numericId": 28, + "displayOrder": 28, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2InstancesInVPC" + }, + { + "id": "b2ea394d-a5af-48c3-a0e2-5fedd84b252a", + "numericId": 27, + "displayOrder": 27, + "tags": [ + "EC2" + ], + "content": "cdk-nag rule: EC2InstanceProfileAttached" + }, + { + "id": "84451178-bb5d-4426-b751-d356b47e4f8e", + "numericId": 26, + "displayOrder": 26, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2InstanceNoPublicIp" + }, + { + "id": "7a5dd7f5-9fb9-4a91-a42a-347d1582a878", + "numericId": 25, + "displayOrder": 25, + "tags": [ + "EC2", + "EBS" + ], + "content": "cdk-nag rule: EC2EBSVolumeEncrypted" + }, + { + "id": "dbd35851-09f6-4979-8a04-a4c6e164b1e9", + "numericId": 24, + "displayOrder": 24, + "tags": [ + "DAX" + ], + "content": "cdk-nag rule: DAXEncrypted" + }, + { + "id": "00a07f21-641a-4587-bdf3-7b540f4a3d72", + "numericId": 23, + "displayOrder": 23, + "tags": [ + "DocumentDB" + ], + "content": "cdk-nag rule: DocumentDBCredentialsInSecretsManager" + }, + { + "id": "a4a01d7e-929a-4b05-9d94-32800cc114a1", + "numericId": 22, + "displayOrder": 22, + "tags": [ + "DocumentDB" + ], + "content": "cdk-nag rule: DocumentDBClusterNonDefaultPort" + }, + { + "id": "d94476ca-88c9-4926-9475-dfa5cdd65820", + "numericId": 21, + "displayOrder": 21, + "tags": [ + "DocumentDB" + ], + "content": "cdk-nag rule: DocumentDBClusterEncryptionAtRest" + }, + { + "id": "b5fc0f6b-28e8-49e6-ba4a-3b2c4654c1d2", + "numericId": 20, + "displayOrder": 20, + "tags": [ + "DMS" + ], + "content": "cdk-nag rule: DMSReplicationNotPublic" + }, + { + "id": "a38a6f2c-709e-4d84-92dc-469d3177cc9a", + "numericId": 19, + "displayOrder": 19, + "tags": [ + "Cognito" + ], + "content": "cdk-nag rule: CognitoUserPoolStrongPasswordPolicy" + }, + { + "id": "aec2e7cc-4c4a-4477-9f08-2dfab6d6f04a", + "numericId": 18, + "displayOrder": 18, + "tags": [ + "Cognito" + ], + "content": "cdk-nag rule: CognitoUserPoolNoUnauthenticatedLogins" + }, + { + "id": "889e8015-010f-4af9-995b-f65e15e9492a", + "numericId": 17, + "displayOrder": 17, + "tags": [ + "Cognito" + ], + "content": "cdk-nag rule: CognitoUserPoolMFA" + }, + { + "id": "908e9591-18d5-4654-9435-56971de5ece1", + "numericId": 16, + "displayOrder": 16, + "tags": [ + "Cognito" + ], + "content": "cdk-nag rule: CognitoUserPoolAPIGWAuthorizer" + }, + { + "id": "b4019a73-d194-48ee-957c-50300e7b4f39", + "numericId": 15, + "displayOrder": 15, + "tags": [ + "Cognito" + ], + "content": "cdk-nag rule: CognitoUserPoolAdvancedSecurityModeEnforced" + }, + { + "id": "c84d3721-1539-444a-af67-bd2fed80735f", + "numericId": 14, + "displayOrder": 14, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectPrivilegedModeDisabled" + }, + { + "id": "ea70a6ca-3fa7-403b-87fc-80e4da6bce1e", + "numericId": 13, + "displayOrder": 13, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectManagedImages" + }, + { + "id": "64a10a2f-8f11-4e98-8d08-8675853b9fef", + "numericId": 12, + "displayOrder": 12, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectKMSEncryptedArtifacts" + }, + { + "id": "89f5fd68-0d19-4c7e-9d91-56832acfa017", + "numericId": 11, + "displayOrder": 11, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectEnvVarAwsCred" + }, + { + "id": "93a7595c-d3b1-4460-a945-734905c19414", + "numericId": 10, + "displayOrder": 10, + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionWAFIntegration" + }, + { + "id": "41220750-87bd-4c85-94f1-999746809166", + "numericId": 9, + "displayOrder": 9, + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionS3OriginAccessIdentity" + }, + { + "id": "89a72e46-d073-4207-bd5a-23636c9a29e6", + "numericId": 8, + "displayOrder": 8, + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionNoOutdatedSSL" + }, + { + "id": "679b9bd9-fd4c-4e23-8f5f-18355483faba", + "numericId": 7, + "displayOrder": 7, + "metadata": [ + { + "key": "Comments", + "value": "[cdk-nag rule definition for CloudFrontDistributionHttpsViewerNoOutdatedSSL](https://github.com/cdklabs/cdk-nag/blob/main/src/rules/cloudfront/CloudFrontDistributionHttpsViewerNoOutdatedSSL.ts)" + } + ], + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionHttpsViewerNoOutdatedSSL" + }, + { + "id": "81de7d44-a27e-4854-a2f4-ec052f327b22", + "numericId": 6, + "displayOrder": 6, + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionGeoRestrictions" + }, + { + "id": "6a8e5465-5e17-4cfd-892d-7a5f4617362b", + "numericId": 5, + "displayOrder": 5, + "tags": [ + "Cloud9" + ], + "content": "cdk-nag rule: Cloud9InstanceNoIngressSystemsManager" + }, + { + "id": "46efe10d-a73d-4ebf-9506-bc39cc929899", + "numericId": 4, + "displayOrder": 4, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: AutoScalingLaunchConfigPublicIpDisabled" + }, + { + "id": "7fffe312-7361-4f89-800b-929cc23c084a", + "numericId": 3, + "displayOrder": 3, + "tags": [ + "Athena" + ], + "content": "cdk-nag rule: AthenaWorkgroupEncryptedQueryResults" + }, + { + "id": "9901b80d-0db7-4554-9dee-b6aa5454b1e3", + "numericId": 2, + "displayOrder": 2, + "tags": [ + "API Gateway" + ], + "content": "cdk-nag rule: APIGWAuthorization" + }, + { + "id": "ce102965-0b66-4352-a6c9-9a99d10b2bfd", + "numericId": 1, + "displayOrder": 1, + "metadata": [ + { + "key": "Comments", + "value": "The API Gateway is associated with a WAF (Web Application Firewall)" + } + ], + "tags": [ + "API Gateway" + ], + "content": "cdk-nag rule: APIGWAssociatedWithWAF" + } + ], + "assumptionLinks": [], + "mitigationLinks": [ + { + "mitigationId": "ce102965-0b66-4352-a6c9-9a99d10b2bfd", + "linkedId": "dc429030-4063-43db-96ea-d60b8ab83152" + }, + { + "mitigationId": "9901b80d-0db7-4554-9dee-b6aa5454b1e3", + "linkedId": "2d370353-bc79-43a7-8e92-68d0850a13d0" + }, + { + "mitigationId": "7fffe312-7361-4f89-800b-929cc23c084a", + "linkedId": "4395c4e3-db64-44c0-8be0-0bcffad7f752" + }, + { + "mitigationId": "46efe10d-a73d-4ebf-9506-bc39cc929899", + "linkedId": "82ffe16c-520c-420e-aa68-d1e9562acc5d" + }, + { + "mitigationId": "6a8e5465-5e17-4cfd-892d-7a5f4617362b", + "linkedId": "c40381b0-0bdf-4e2a-86ba-966634fab370" + }, + { + "mitigationId": "81de7d44-a27e-4854-a2f4-ec052f327b22", + "linkedId": "8c9cd385-7a3d-486d-90fc-5b9f3b28a04a" + }, + { + "mitigationId": "679b9bd9-fd4c-4e23-8f5f-18355483faba", + "linkedId": "8cde9550-4aac-4792-851f-e6ac01b3ae92" + }, + { + "mitigationId": "89a72e46-d073-4207-bd5a-23636c9a29e6", + "linkedId": "c7d756f0-0576-4644-a9b3-afea5bd52a7c" + }, + { + "mitigationId": "41220750-87bd-4c85-94f1-999746809166", + "linkedId": "d4378c9b-e680-41c1-8cc2-136e124461dd" + }, + { + "mitigationId": "93a7595c-d3b1-4460-a945-734905c19414", + "linkedId": "3baec34a-5ed0-459d-90d9-9e5497e29751" + }, + { + "mitigationId": "89f5fd68-0d19-4c7e-9d91-56832acfa017", + "linkedId": "493365cb-ff0b-411b-bc10-aaa97b6306fa" + }, + { + "mitigationId": "64a10a2f-8f11-4e98-8d08-8675853b9fef", + "linkedId": "7b1dbdd4-2cea-4b16-a15b-51b05822f972" + }, + { + "mitigationId": "ea70a6ca-3fa7-403b-87fc-80e4da6bce1e", + "linkedId": "3e3ee2f1-053d-4e40-8917-52ce4f45ea56" + }, + { + "mitigationId": "c84d3721-1539-444a-af67-bd2fed80735f", + "linkedId": "9d2c9e3b-f5c8-42af-8f63-4bd2309cf0d9" + }, + { + "mitigationId": "b4019a73-d194-48ee-957c-50300e7b4f39", + "linkedId": "3b6b28ec-be93-41c1-b93c-8df4411a821a" + }, + { + "mitigationId": "b4019a73-d194-48ee-957c-50300e7b4f39", + "linkedId": "36547ec4-c4d6-487d-8fdf-83cb2975473e" + }, + { + "mitigationId": "908e9591-18d5-4654-9435-56971de5ece1", + "linkedId": "9893d5cc-6cff-4d3e-8bd2-f7c2f4af58f2" + }, + { + "mitigationId": "889e8015-010f-4af9-995b-f65e15e9492a", + "linkedId": "0837eafd-540f-4a08-a602-a577d6dcdbc0" + }, + { + "mitigationId": "aec2e7cc-4c4a-4477-9f08-2dfab6d6f04a", + "linkedId": "ae94934d-1eda-4be0-befd-1e5c75cda4e2" + }, + { + "mitigationId": "a38a6f2c-709e-4d84-92dc-469d3177cc9a", + "linkedId": "eb82eea2-d949-4fd4-b5d2-1516b9c977bb" + }, + { + "mitigationId": "b5fc0f6b-28e8-49e6-ba4a-3b2c4654c1d2", + "linkedId": "9f6177a5-0f9f-408b-b0d1-9e8067b60dc2" + }, + { + "mitigationId": "d94476ca-88c9-4926-9475-dfa5cdd65820", + "linkedId": "6e86656c-5779-4695-9a8f-1caa535bb4e9" + }, + { + "mitigationId": "a4a01d7e-929a-4b05-9d94-32800cc114a1", + "linkedId": "76de4625-b01a-4cf4-8cbb-b5a1a1f75ebf" + }, + { + "mitigationId": "00a07f21-641a-4587-bdf3-7b540f4a3d72", + "linkedId": "a5fba694-7098-4263-8001-305f13512f3b" + }, + { + "mitigationId": "dbd35851-09f6-4979-8a04-a4c6e164b1e9", + "linkedId": "28a2d363-365e-4959-a35c-d51eaf74af5f" + }, + { + "mitigationId": "7a5dd7f5-9fb9-4a91-a42a-347d1582a878", + "linkedId": "9bbb493a-c435-420a-aa35-3fa992064127" + }, + { + "mitigationId": "84451178-bb5d-4426-b751-d356b47e4f8e", + "linkedId": "82ffe16c-520c-420e-aa68-d1e9562acc5d" + }, + { + "mitigationId": "84451178-bb5d-4426-b751-d356b47e4f8e", + "linkedId": "c40381b0-0bdf-4e2a-86ba-966634fab370" + }, + { + "mitigationId": "dbd35851-09f6-4979-8a04-a4c6e164b1e9", + "linkedId": "c40381b0-0bdf-4e2a-86ba-966634fab370" + }, + { + "mitigationId": "b2ea394d-a5af-48c3-a0e2-5fedd84b252a", + "linkedId": "71e166df-1f57-4f3c-a1af-919180bcdb65" + }, + { + "mitigationId": "1232e7b6-14d3-49a2-b323-cd7b789918ed", + "linkedId": "801739c7-11d2-4bbe-8368-4d49c501e39f" + }, + { + "mitigationId": "dec3b995-d1ed-4a35-a3f3-b4053f05b3ab", + "linkedId": "aadd2e92-221b-4a13-90e2-7f5b41e80709" + }, + { + "mitigationId": "0edef48e-478a-4354-afba-04cbd8a678af", + "linkedId": "8c3352e2-b817-4139-9256-81e75ff127f7" + }, + { + "mitigationId": "c09ffb80-6a08-4d17-b497-6fadcf3f723e", + "linkedId": "961651aa-830e-4b67-9755-1541d005475b" + }, + { + "mitigationId": "a3adc4bc-12e6-4e51-9a3b-f70173626aed", + "linkedId": "310b7a7f-e13c-44a3-bb3a-91ad7bf9ba98" + }, + { + "mitigationId": "30b62ffd-ce1e-423c-a715-458971016ced", + "linkedId": "5f5adfdb-98cf-4580-86bb-42ae5bd2bb7b" + }, + { + "mitigationId": "7df3fa44-ac61-44f4-acd5-9ab2b78f2d98", + "linkedId": "61009521-4be1-4bf7-b0cd-ada8401ec7f7" + }, + { + "mitigationId": "fba0d1b6-ea6e-46cb-85c8-01f0244b1d66", + "linkedId": "dd2bfe1d-f75c-42cb-a2cd-6dfb949318e1" + }, + { + "mitigationId": "0c4211b1-4bd1-464d-846e-82353ed1ebfa", + "linkedId": "1fc40b42-ddf8-4632-8584-00d2fe423f8f" + }, + { + "mitigationId": "22982dbd-4fd5-47fc-804c-03f88e4f479f", + "linkedId": "b34692af-8e67-46d1-8393-2f5c8264c783" + }, + { + "mitigationId": "24f0ecef-8c8b-4d53-b5ad-be63739587fa", + "linkedId": "813c3fc1-33bc-4823-9f9c-91b2df1f4030" + }, + { + "mitigationId": "c00d5353-11bb-48b0-9abd-4ac291dd4cb3", + "linkedId": "63c13cf9-adcc-4db5-b0a7-e58a455f1190" + }, + { + "mitigationId": "2202a747-7921-4fff-94ec-24467b86bb55", + "linkedId": "9162a0f9-b47f-49b9-8422-220ac65697c6" + }, + { + "mitigationId": "7fde0f89-ef45-49ec-a88d-3a8f17aa9a8a", + "linkedId": "e89e4939-4f14-4fb0-9be2-ce9955dd1a3b" + }, + { + "mitigationId": "f2e8e52c-3b0f-4256-9497-d2f6743971c7", + "linkedId": "18cb5978-912c-4fd8-bae2-9f4339f342b3" + }, + { + "mitigationId": "f2e8e52c-3b0f-4256-9497-d2f6743971c7", + "linkedId": "df2c6877-518f-4d73-97ee-e79c9f0bde84" + }, + { + "mitigationId": "98e3e1a6-7548-405d-a896-abbda186e920", + "linkedId": "f4bd72a6-d939-42c7-9433-6d0d8850abbc" + }, + { + "mitigationId": "6a6b668e-63f1-4bd5-bfd3-dbcaf5386a69", + "linkedId": "5ee158eb-f45c-43af-bfe4-b22bd4a38b8b" + }, + { + "mitigationId": "0c99176f-071d-4e9a-97d7-90fe9a7f1293", + "linkedId": "aa4ace87-4350-4e06-b975-2cb9a3dda05a" + }, + { + "mitigationId": "01867f64-62e3-4981-a571-07c42ce35dfd", + "linkedId": "1d6b6a27-939a-4515-a3ac-dda8cb2cbebe" + }, + { + "mitigationId": "c90a9a7a-1536-4dc3-a582-3eb0abaddd8b", + "linkedId": "5abdfbc3-cc06-477c-95ea-9be582df206b" + }, + { + "mitigationId": "c8503353-a75f-4e28-a156-4424f9a28c76", + "linkedId": "7f1c16c7-7551-4aaa-b7c1-8805c31b3e11" + }, + { + "mitigationId": "38e3b1ce-484a-4e02-a00c-cd46686fd3ba", + "linkedId": "9a2693b0-a706-4ada-9b0f-5cf06be35597" + }, + { + "mitigationId": "ca237931-d8f4-487a-9cf3-72d81b7107ab", + "linkedId": "9676651f-67e7-4e99-81f3-e3f7b4b68951" + }, + { + "mitigationId": "a19bfb5e-6416-49d5-ad97-48476a92921f", + "linkedId": "9d7f556d-56f3-422f-867e-8c1d0be77763" + }, + { + "mitigationId": "06342334-a5c7-45f5-9325-6c8bb097f005", + "linkedId": "54847997-f8e0-41ce-94f4-da04703e9ea2" + }, + { + "mitigationId": "0ba2992b-2d77-4864-b58b-f52bacdc4349", + "linkedId": "29753d15-d761-4051-a692-5f2b43a5d952" + }, + { + "mitigationId": "da85ab97-eb06-4c15-9782-5a7a1924c7d4", + "linkedId": "1c62b52e-f3ba-4968-a14d-745691b706f6" + }, + { + "mitigationId": "ca417660-79a6-4725-b498-7406ffc8a9f5", + "linkedId": "1c62b52e-f3ba-4968-a14d-745691b706f6" + }, + { + "mitigationId": "1a74ef32-b240-4173-9f02-0e8ebbc20191", + "linkedId": "1c62b52e-f3ba-4968-a14d-745691b706f6" + }, + { + "mitigationId": "4fe4bbaf-08fa-437d-b5ea-1e010610133b", + "linkedId": "1c62b52e-f3ba-4968-a14d-745691b706f6" + }, + { + "mitigationId": "f1601e79-56fe-4863-8466-7d383ed65274", + "linkedId": "2720ca94-372b-4f20-885c-363540194948" + }, + { + "mitigationId": "c22a535f-d743-40ba-8531-e979c1235cb7", + "linkedId": "35bb299c-4a0a-40c7-9904-ea94463fc972" + }, + { + "mitigationId": "d0d6e348-0ed5-4465-b275-ba4f301097e1", + "linkedId": "29b040ef-2af1-47c9-9bd7-ef1982c6898d" + }, + { + "mitigationId": "fcd9742a-30eb-4303-97e7-206e4a1f63fd", + "linkedId": "5d521ccc-ca9c-4790-b045-0a1e26de9aa0" + }, + { + "mitigationId": "4487d987-db5b-4a81-a6cb-ab736509ae2e", + "linkedId": "105eadf1-cd9a-41ae-a045-0a841321c9e6" + }, + { + "mitigationId": "00dc16be-7bce-4b82-830d-b3ac223a4fbf", + "linkedId": "6de74250-8b27-4196-bb80-e916737f42c4" + }, + { + "mitigationId": "5e01f259-e40f-460e-a1a6-0666398a2c7a", + "linkedId": "2db78753-b02e-4fc0-bdd6-1331f8340514" + }, + { + "mitigationId": "8f608620-f1a1-40e8-b34b-f6ea547fe0fa", + "linkedId": "f445b352-3f3c-4194-89f9-d7d37dc034e5" + }, + { + "mitigationId": "7f0815f2-c84e-4cd9-9859-3ed693729cab", + "linkedId": "ee0b0c99-e8b7-4074-81d2-d060bf81dacd" + }, + { + "mitigationId": "8912a402-b365-4d39-ab63-321825adbd1e", + "linkedId": "a960e824-cd07-4606-b6bb-f35ce27bbf5a" + }, + { + "mitigationId": "c22f8d36-4546-4e39-9eea-156fbbc7d99b", + "linkedId": "acb24ce7-a489-4c88-a12e-c09f212c569c" + }, + { + "mitigationId": "6288512e-5ebc-433e-bef5-a3f038119b69", + "linkedId": "9aab600f-250b-4b1f-94f5-3bf59db093b9" + }, + { + "mitigationId": "28b7cc4b-21f3-4155-a4e3-4f3dcb5e9117", + "linkedId": "47e30a3b-8666-47d7-b92f-43510bb87615" + }, + { + "mitigationId": "972fb272-b77f-4f32-95f0-bb47023d3770", + "linkedId": "4c4f232c-a735-431b-8717-9d8e02faae3d" + }, + { + "mitigationId": "972fb272-b77f-4f32-95f0-bb47023d3770", + "linkedId": "9aab600f-250b-4b1f-94f5-3bf59db093b9" + }, + { + "mitigationId": "68089d75-7a9f-4a48-b742-95dde35b069a", + "linkedId": "89dd20e6-148c-4f23-9f58-28306b3816b6" + }, + { + "mitigationId": "e1239e2d-9267-4608-ab0d-09d4eab63d7d", + "linkedId": "9aab600f-250b-4b1f-94f5-3bf59db093b9" + }, + { + "mitigationId": "4f2ac79c-f343-4916-9b8c-b078544f81a5", + "linkedId": "5d523d1a-03f1-414a-be76-e0bb3b606dde" + }, + { + "mitigationId": "16a9eba9-5e70-4d94-b9d9-d77cf17c522f", + "linkedId": "e5c4f1d0-113a-4dfd-94c5-8072226608e4" + }, + { + "mitigationId": "cdfb2f22-d096-468c-ae64-c8a63e6d03d5", + "linkedId": "978e7c53-4c2f-49c2-86ce-8d3a14bb5cb4" + }, + { + "mitigationId": "dc7ad88b-55b0-480d-9023-b9ac660b388e", + "linkedId": "e5c4f1d0-113a-4dfd-94c5-8072226608e4" + }, + { + "mitigationId": "5382b34e-1cee-4fe4-acab-1e1ef283437d", + "linkedId": "ef634b32-084b-42f6-ae5c-4e65b3953ba5" + }, + { + "mitigationId": "59a9c68e-b899-4dea-b326-ebebda148f00", + "linkedId": "e5c4f1d0-113a-4dfd-94c5-8072226608e4" + }, + { + "mitigationId": "de0b05cd-ff7d-4993-81c5-5bc5585151a4", + "linkedId": "172ce9d2-8159-4c70-a2b7-70dc846bdf70" + }, + { + "mitigationId": "55c0cdfd-c8e5-4d41-a700-de7a89557782", + "linkedId": "012e2241-559a-45f8-98ae-df21d7012639" + }, + { + "mitigationId": "c75b2076-9a00-4808-8525-a25d629fb784", + "linkedId": "aa52a71f-4293-47c2-aeb1-080cadb9c607" + }, + { + "mitigationId": "857bbf82-30f5-40f0-9ffd-60b6b67053e9", + "linkedId": "4309ecb8-b7d1-4251-88f3-8f4f4635f046" + }, + { + "mitigationId": "b08bdd06-48c1-4c3f-8401-464d667e92e0", + "linkedId": "aa52a71f-4293-47c2-aeb1-080cadb9c607" + }, + { + "mitigationId": "46e8c83a-a4d0-428d-ba9e-b4c9e68bbc24", + "linkedId": "aa52a71f-4293-47c2-aeb1-080cadb9c607" + }, + { + "mitigationId": "232d24ee-cfd5-4351-bd5d-3dfdcf2508ee", + "linkedId": "807bfa40-afe3-42a8-b7c5-2800fe7f7bf8" + }, + { + "mitigationId": "78d761ef-4297-45d1-ae1b-7ba545d39130", + "linkedId": "7f8aaef1-4f43-4329-add1-9bda1a25cc77" + }, + { + "mitigationId": "0ae5ca12-88c7-4648-a1e8-28ad585c3336", + "linkedId": "8c383856-988d-45a4-bc92-5c9aab42aab3" + }, + { + "mitigationId": "646feb9c-6f18-4307-8a90-8a44b851d176", + "linkedId": "1b240cb7-3557-41e7-9c19-21ebc73ad0ec" + }, + { + "mitigationId": "c4b91bbd-8e0f-457e-97e1-3b940b2007ef", + "linkedId": "8c383856-988d-45a4-bc92-5c9aab42aab3" + }, + { + "mitigationId": "1483c264-8b13-4954-8e79-97bb63163b57", + "linkedId": "8c383856-988d-45a4-bc92-5c9aab42aab3" + }, + { + "mitigationId": "b19fd780-64a3-42c6-a0d2-92833af17e40", + "linkedId": "77e519f0-641e-4b99-96a3-db0130381c97" + }, + { + "mitigationId": "c0f8d761-b616-49d4-b60e-d9d413c91f19", + "linkedId": "cc8b9fcb-dd2a-41ad-a4f1-11e93ae0b031" + }, + { + "mitigationId": "b6cfe99f-842f-4567-8611-92c7cea45eb2", + "linkedId": "1ed4872c-279d-444d-9343-aca8bb343d00" + }, + { + "mitigationId": "d23b82f2-f274-42eb-9edd-75ddc0ca75d2", + "linkedId": "bd25bc81-1e9e-4982-a47d-05848e13af6c" + }, + { + "mitigationId": "75327602-a8f0-48ed-b635-305678ef5893", + "linkedId": "bd25bc81-1e9e-4982-a47d-05848e13af6c" + }, + { + "mitigationId": "fff9fac4-1512-4a49-81a3-88e420f6c110", + "linkedId": "90619d5b-6450-4108-8013-2eaafc5788b5" + }, + { + "mitigationId": "35eefa29-d011-4b50-a7a8-a204a2b01b34", + "linkedId": "7f17d020-6368-48ee-b934-c9272de71242" + }, + { + "mitigationId": "7e9478e3-4571-4c36-bb7c-bb33acf4ec08", + "linkedId": "9d47bd52-9dbc-4eee-8e55-04a3fc8064c4" + }, + { + "mitigationId": "a1aae9d0-1511-4f93-841e-801e9b47976f", + "linkedId": "49a1ba28-3c57-48a9-a1d2-798b633be2e2" + }, + { + "mitigationId": "a92c9799-aba4-45f9-a639-8c922d7706d0", + "linkedId": "a3434833-a75f-4c0a-8ef2-fcc776878231" + }, + { + "mitigationId": "be57de80-6cb4-420d-80bc-c7fb6a97d6ea", + "linkedId": "afe2db28-0f4c-4deb-b894-184ed223e560" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "82ffe16c-520c-420e-aa68-d1e9562acc5d" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "c40381b0-0bdf-4e2a-86ba-966634fab370" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "9f6177a5-0f9f-408b-b0d1-9e8067b60dc2" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "8c3352e2-b817-4139-9256-81e75ff127f7" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "961651aa-830e-4b67-9755-1541d005475b" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "9162a0f9-b47f-49b9-8422-220ac65697c6" + }, + { + "mitigationId": "f6d8a0a5-e5ed-4f9a-b3a6-55bd45df7e3c", + "linkedId": "1d6b6a27-939a-4515-a3ac-dda8cb2cbebe" + } + ], + "threats": [ + { + "id": "afe2db28-0f4c-4deb-b894-184ed223e560", + "numericId": 92, + "displayOrder": 92, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "T" + ] + } + ], + "tags": [ + "Timestream", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the Timestream database", + "threatAction": "view or modify the data", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the Timestream database can view or modify the data, resulting in reduced confidentiality and/or integrity of this application's data" + }, + { + "id": "a3434833-a75f-4c0a-8ef2-fcc776878231", + "numericId": 91, + "displayOrder": 91, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T", + "I" + ] + } + ], + "tags": [ + "SQS", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the Amazon SQS endpoint", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the Amazon SQS endpoint can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application" + }, + { + "id": "49a1ba28-3c57-48a9-a1d2-798b633be2e2", + "numericId": 90, + "displayOrder": 90, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "S", + "T" + ] + } + ], + "tags": [ + "SQS", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the SQS (Simple Queue Service) topic", + "threatAction": "view or modify the SQS messages", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with access to underlying storage used for the SQS (Simple Queue Service) topic can view or modify the SQS messages, resulting in reduced confidentiality and/or integrity of this application" + }, + { + "id": "9d47bd52-9dbc-4eee-8e55-04a3fc8064c4", + "numericId": 89, + "displayOrder": 89, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "T" + ] + } + ], + "tags": [ + "SNS", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the publisher and the Amazon SNS endpoint", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who is in a person-in-the-middle position between the publisher and the Amazon SNS endpoint can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application's data" + }, + { + "id": "7f17d020-6368-48ee-b934-c9272de71242", + "numericId": 88, + "displayOrder": 88, + "tags": [ + "SNS", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the SNS (Simple Notification Service) topic", + "threatAction": "view the SNS messages", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the SNS (Simple Notification Service) topic can view the SNS messages, resulting in reduced confidentiality and/or integrity of this application's data" + }, + { + "id": "90619d5b-6450-4108-8013-2eaafc5788b5", + "numericId": 87, + "displayOrder": 87, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "S", + "T", + "I", + "E" + ] + } + ], + "tags": [ + "Secrets Manager", + "AuthN" + ], + "threatSource": "threat actor", + "prerequisites": "who has obtained a long-lived secret (e.g. password)", + "threatAction": "spoof an authenticated user or system", + "threatImpact": "the actor being able to do anything the user or system can do", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who has obtained a long-lived secret (e.g. password) can spoof an authenticated user or system, which leads to the actor being able to do anything the user or system can do, negatively impacting this application" + }, + { + "id": "bd25bc81-1e9e-4982-a47d-05848e13af6c", + "numericId": 86, + "displayOrder": 86, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "E" + ] + } + ], + "tags": [ + "SageMaker", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with interactive access to the SageMaker notebook", + "threatAction": "take advantage of unfiltered / unrestricted access to the internet via the Sagemaker VPC", + "threatImpact": "download malicious code or tools; or exfiltrate data bypassing any centralised internet ingress/egress controls that may in place within your own VPC", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with interactive access to the SageMaker notebook can take advantage of unfiltered / unrestricted access to the internet via the Sagemaker VPC, which leads to download malicious code or tools; or exfiltrate data bypassing any centralised internet ingress/egress controls that may in place within your own VPC, negatively impacting this application" + }, + { + "id": "1ed4872c-279d-444d-9343-aca8bb343d00", + "numericId": 85, + "displayOrder": 85, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "T" + ] + } + ], + "tags": [ + "SageMaker", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the SageMaker notebook", + "threatAction": "view the contents of the notebook (e.g. code or query results)", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the SageMaker notebook can view the contents of the notebook (e.g. code or query results), resulting in reduced confidentiality and/or integrity of this application's data" + }, + { + "id": "cc8b9fcb-dd2a-41ad-a4f1-11e93ae0b031", + "numericId": 84, + "displayOrder": 84, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I" + ] + } + ], + "tags": [ + "S3", + "Network Access" + ], + "threatSource": "external threat actor", + "prerequisites": "who has discovered misconfigured S3 hosted website", + "threatAction": "bypass the protections put in place by CloudFront (e.g. geo blocking)", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "An external threat actor who has discovered misconfigured S3 hosted website can bypass the protections put in place by CloudFront (e.g. geo blocking), resulting in reduced confidentiality of this application's data" + }, + { + "id": "77e519f0-641e-4b99-96a3-db0130381c97", + "numericId": 83, + "displayOrder": 83, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "T" + ] + } + ], + "tags": [ + "S3", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the Amazon S3 bucket endpoint", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the Amazon S3 bucket endpoint can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application's data" + }, + { + "id": "1b240cb7-3557-41e7-9c19-21ebc73ad0ec", + "numericId": 82, + "displayOrder": 82, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "R" + ] + } + ], + "tags": [ + "S3", + "Repudiation" + ], + "threatSource": "threat actor", + "prerequisites": "who is authenticated and authorized", + "threatAction": "deny taking a action associated with an Amazon S3 bucket", + "threatImpact": "lack of knowledge/proof of who took the action", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is authenticated and authorized can deny taking an action associated with an Amazon S3 bucket, which leads to lack of knowledge/proof of who took the action" + }, + { + "id": "8c383856-988d-45a4-bc92-5c9aab42aab3", + "numericId": 81, + "displayOrder": 81, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T", + "I" + ] + } + ], + "tags": [ + "S3", + "Public Access" + ], + "threatSource": "threat actor", + "prerequisites": "who has discovered a S3 bucket configured for public read or write", + "threatAction": "read or write data to or from the S3 bucket", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who has discovered a S3 bucket configured for public read or write can read or write data to or from the S3 bucket, resulting in reduced confidentiality, integrity and/or availability of this application's data" + }, + { + "id": "7f8aaef1-4f43-4329-add1-9bda1a25cc77", + "numericId": 80, + "displayOrder": 80, + "tags": [ + "Redshift", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the Redshift cluster", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the Redshift cluster can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application's data" + }, + { + "id": "807bfa40-afe3-42a8-b7c5-2800fe7f7bf8", + "numericId": 79, + "displayOrder": 79, + "tags": [ + "Redshift", + "Vuln Management" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the Redshift cluster", + "threatAction": "attempt to take advantage of a known vulnerability in a component exposed by Redshift", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the Redshift cluster can attempt to take advantage of a known vulnerability in a component exposed by Redshift, negatively impacting this application" + }, + { + "id": "4309ecb8-b7d1-4251-88f3-8f4f4635f046", + "numericId": 78, + "displayOrder": 78, + "tags": [ + "Redshift", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the Redshift cluster listener", + "threatAction": "perform a network probe the database using it's default port", + "threatImpact": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the Redshift cluster listener can perform a network probe the database using it's default port, which leads to perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "aa52a71f-4293-47c2-aeb1-080cadb9c607", + "numericId": 77, + "displayOrder": 77, + "tags": [ + "Redshift", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the Redshift cluster listener", + "threatAction": "brute-force the database credentials", + "threatImpact": "the ability to view or modify data", + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with a network path to the Redshift cluster listener can brute-force the database credentials, which leads to the ability to view or modify data, negatively impacting this application's data" + }, + { + "id": "012e2241-559a-45f8-98ae-df21d7012639", + "numericId": 76, + "displayOrder": 76, + "tags": [ + "Redshift", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the Redshift cluster", + "threatAction": "view the contents of the database", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the Redshift cluster can view the contents of the database, resulting in reduced confidentiality of this application's data" + }, + { + "id": "172ce9d2-8159-4c70-a2b7-70dc846bdf70", + "numericId": 75, + "displayOrder": 75, + "tags": [ + "RDS", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the RDS cluster", + "threatAction": "view the contents of the database", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the RDS cluster can view the contents of the database, resulting in reduced confidentiality of this application's data" + }, + { + "id": "ef634b32-084b-42f6-ae5c-4e65b3953ba5", + "numericId": 74, + "displayOrder": 74, + "tags": [ + "RDS", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the RDS cluster listener", + "threatAction": "perform a network probe the database using it's default port", + "threatImpact": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the RDS cluster listener can perform a network probe the database using it's default port, which leads to perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "978e7c53-4c2f-49c2-86ce-8d3a14bb5cb4", + "numericId": 73, + "displayOrder": 73, + "tags": [ + "RDS", + "Vuln Management" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the RDS cluster or instance", + "threatAction": "attempt to take advantage of a known vulnerability in a component exposed by RDS", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the RDS cluster or instance can attempt to take advantage of a known vulnerability in a component exposed by RDS, negatively impacting this application" + }, + { + "id": "e5c4f1d0-113a-4dfd-94c5-8072226608e4", + "numericId": 72, + "displayOrder": 72, + "tags": [ + "RDS", + "AuthN", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the RDS database listener", + "threatAction": "brute-force the database credentials", + "threatImpact": "the ability to view or modify data", + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with a network path to the RDS database listener can brute-force the database credentials, which leads to the ability to view or modify data, negatively impacting this application's data" + }, + { + "id": "5d523d1a-03f1-414a-be76-e0bb3b606dde", + "numericId": 71, + "displayOrder": 71, + "tags": [ + "Quicksight", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between Quicksight and it's data source", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who is in a person-in-the-middle position between Quicksight and it's data source can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application's data" + }, + { + "id": "89dd20e6-148c-4f23-9f58-28306b3816b6", + "numericId": 70, + "displayOrder": 70, + "tags": [ + "OpenSearch", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the OpenSearch nodes", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who is in a person-in-the-middle position between the OpenSearch nodes can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application's data" + }, + { + "id": "47e30a3b-8666-47d7-b92f-43510bb87615", + "numericId": 69, + "displayOrder": 69, + "tags": [ + "OpenSearch", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the OpenSearch cluster", + "threatAction": "view the contents of the database", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the OpenSearch cluster can view the contents of the database, resulting in reduced confidentiality of this application's data" + }, + { + "id": "9aab600f-250b-4b1f-94f5-3bf59db093b9", + "numericId": 68, + "displayOrder": 68, + "tags": [ + "OpenSearch", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the OpenSearch domain", + "threatAction": "perform reconnaissance and intrusion activities against the exposed attack surface", + "threatImpact": "the ability to view or modify data", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the OpenSearch domain can perform reconnaissance and intrusion activities against the exposed attack surface, which leads to the ability to view or modify data, negatively impacting this application" + }, + { + "id": "acb24ce7-a489-4c88-a12e-c09f212c569c", + "numericId": 67, + "displayOrder": 67, + "tags": [ + "Neptune", + "AuthN" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the Neptune database listener", + "threatAction": "brute-force the database credentials", + "threatImpact": "the ability to view or modify data", + "impactedAssets": [ + "this application's Neptune data" + ], + "statement": "An external threat actor with a network path to the Neptune database listener can brute-force the database credentials, which leads to the ability to view or modify data, negatively impacting this application's Neptune data" + }, + { + "id": "a960e824-cd07-4606-b6bb-f35ce27bbf5a", + "numericId": 66, + "displayOrder": 66, + "tags": [ + "Neptune", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the Neptune cluster", + "threatAction": "view the contents of the database", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's Neptune data" + ], + "statement": "A threat actor with access to underlying storage used for the Neptune cluster can view the contents of the database, resulting in reduced confidentiality of this application's Neptune data" + }, + { + "id": "ee0b0c99-e8b7-4074-81d2-d060bf81dacd", + "numericId": 65, + "displayOrder": 65, + "tags": [ + "Neptune", + "Vuln Management" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the Neptune cluster or instance", + "threatAction": "attempt to take advantage of a known vulnerability in a component exposed by Neptune", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the Neptune cluster or instance can attempt to take advantage of a known vulnerability in a component exposed by Neptune, negatively impacting this application" + }, + { + "id": "f445b352-3f3c-4194-89f9-d7d37dc034e5", + "numericId": 64, + "displayOrder": 64, + "tags": [ + "MSK", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the Amazon MSK (Managed Streaming for Apache Kafka) cluster broker", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the Amazon MSK (Managed Streaming for Apache Kafka) cluster broker can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses" + }, + { + "id": "2db78753-b02e-4fc0-bdd6-1331f8340514", + "numericId": 63, + "displayOrder": 63, + "tags": [ + "MediaStore", + "AuthZ" + ], + "threatSource": "threat actor", + "prerequisites": "with access to a valid and authorized IAM Principal", + "threatAction": "take advantage of unnecessary permissions included in the associated MediaStore container policy", + "threatImpact": "the actor being able to do anything the user can do (for example: perform all supported operations on the container)", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with access to a valid and authorized IAM Principal can take advantage of unnecessary permissions included in the associated MediaStore container policy, which leads to the actor being able to do anything the user can do (for example: perform all supported operations on the container), negatively impacting this application" + }, + { + "id": "6de74250-8b27-4196-bb80-e916737f42c4", + "numericId": 62, + "displayOrder": 62, + "tags": [ + "MediaStore", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the MediaStore container", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the MediaStore container can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses" + }, + { + "id": "105eadf1-cd9a-41ae-a045-0a841321c9e6", + "numericId": 61, + "displayOrder": 61, + "tags": [ + "MediaStore", + "XSS" + ], + "threatSource": "external threat actor", + "prerequisites": "who has discovered a XSS (Cross-site scripting) vulnerability on assets hosted on MediaStore container", + "threatAction": "cause unintended external resources such as javascript, images or videos to loaded within the context of the website", + "threatImpact": "", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor who has discovered an XSS (Cross-site scripting) vulnerability on assets hosted on MediaStore container can cause unintended external resources such as javascript, images or videos to loaded within the context of the website, negatively impacting this application" + }, + { + "id": "5d521ccc-ca9c-4790-b045-0a1e26de9aa0", + "numericId": 60, + "displayOrder": 60, + "tags": [ + "Lambda", + "Vuln Management" + ], + "threatSource": "threat actor", + "prerequisites": "with the ability to invoke or interact with a Lambda function", + "threatAction": "take advantage of a disclosed vulnerability within the runtime version used for a non-container based Lambda function", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with the ability to invoke or interact with a Lambda function can take advantage of a disclosed vulnerability within the runtime version used for a non-container based Lambda function, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "29b040ef-2af1-47c9-9bd7-ef1982c6898d", + "numericId": 59, + "displayOrder": 59, + "tags": [ + "Lambda", + "Public access" + ], + "threatSource": "external threat actor", + "prerequisites": "who has discovered the Lambda Function URL", + "threatAction": "invoke the function without any authentication", + "threatImpact": "allowing the actor to perform the actions permitted by the associated Lambda function", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor who has discovered the Lambda Function URL can invoke the function without any authentication, which leads to allowing the actor to perform the actions permitted by the associated Lambda function, negatively impacting this application" + }, + { + "id": "35bb299c-4a0a-40c7-9904-ea94463fc972", + "numericId": 58, + "displayOrder": 58, + "tags": [ + "Kinesis", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for a Kinesis Data Stream", + "threatAction": "view the contents of the stream", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's Kinesis Data Stream" + ], + "statement": "A threat actor with access to underlying storage used for a Kinesis Data Stream can view the contents of the stream, resulting in reduced confidentiality of this application's Kinesis Data Stream" + }, + { + "id": "2720ca94-372b-4f20-885c-363540194948", + "numericId": 57, + "displayOrder": 57, + "tags": [ + "Kinesis", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for a Kinesis Data Firehouse delivery stream", + "threatAction": "view the contents of the stream", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's Kinesis Data Stream", + "this application's Kinesis Data Firehouse delivery stream" + ], + "statement": "A threat actor with access to underlying storage used for a Kinesis Data Firehouse delivery stream can view the contents of the stream, resulting in reduced confidentiality of this application's Kinesis Data Stream and this application's Kinesis Data Firehouse delivery stream" + }, + { + "id": "1c62b52e-f3ba-4968-a14d-745691b706f6", + "numericId": 56, + "displayOrder": 56, + "tags": [ + "IAM" + ], + "threatSource": "threat actor", + "prerequisites": "with access to a valid IAM Principal", + "threatAction": "take advantage of unnecessary permissions included in the associated IAM Policy", + "threatImpact": "the actor being able to do anything the user can do", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with access to a valid IAM Principal can take advantage of unnecessary permissions included in the associated IAM Policy, which leads to the actor being able to do anything the user can do, negatively impacting this application" + }, + { + "id": "29753d15-d761-4051-a692-5f2b43a5d952", + "numericId": 55, + "displayOrder": 55, + "tags": [ + "Glue" + ], + "threatSource": "threat actor", + "prerequisites": "with access to Amazon S3 bucket used for Glue job bookmarks", + "threatAction": "view the contents of the bookmarks", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's Glue job bookmarks" + ], + "statement": "A threat actor with access to Amazon S3 bucket used for Glue job bookmarks can view the contents of the bookmarks, resulting in reduced confidentiality of this application's Glue job bookmarks" + }, + { + "id": "54847997-f8e0-41ce-94f4-da04703e9ea2", + "numericId": 54, + "displayOrder": 54, + "tags": [ + "Glue" + ], + "threatSource": "threat actor", + "prerequisites": "with access to the CloudWatch Log storage", + "threatAction": "view or modify the contents of the logs", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "glue crawler or job logs" + ], + "statement": "A threat actor with access to the CloudWatch Log storage can view or modify the contents of the logs, resulting in reduced confidentiality and/or integrity of glue crawler or job logs" + }, + { + "id": "9d7f556d-56f3-422f-867e-8c1d0be77763", + "numericId": 53, + "displayOrder": 53, + "tags": [ + "EventBridge" + ], + "threatSource": "external threat actor", + "prerequisites": "who has discovered the Event Bridge event bus (e.g. Endpoint ID)", + "threatAction": "put arbitrary events onto the bus", + "threatImpact": "those events being processed by the application", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor who has discovered the Event Bridge event bus (e.g. Endpoint ID) can put arbitrary events onto the bus, which leads to those events being processed by the application, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "9676651f-67e7-4e99-81f3-e3f7b4b68951", + "numericId": 52, + "displayOrder": 52, + "tags": [ + "EMR" + ], + "threatSource": "threat actor", + "prerequisites": "with access to the EMR local storage", + "threatAction": "view or modify the contents on the disk", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data within the EMR cluster" + ], + "statement": "A threat actor with access to the EMR local storage can view or modify the contents on the disk, resulting in reduced confidentiality and/or integrity of data within the EMR cluster" + }, + { + "id": "9a2693b0-a706-4ada-9b0f-5cf06be35597", + "numericId": 51, + "displayOrder": 51, + "tags": [ + "EMR" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the EMR cluster", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the EMR cluster can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses" + }, + { + "id": "7f1c16c7-7551-4aaa-b7c1-8805c31b3e11", + "numericId": 50, + "displayOrder": 50, + "tags": [ + "EMR" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the EMR cluster listener not configured with authentication", + "threatAction": "perform unauthenticated commands to the cluster", + "threatImpact": "", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the EMR cluster listener not configured with authentication can perform unauthenticated commands to the cluster, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "f00ee4a4-18da-412e-927f-6b79e0315000", + "numericId": 49, + "displayOrder": 49, + "tags": [ + "CLB" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the CLB (Classic Load Balancer)", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the CLB (Classic Load Balancer) can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses" + }, + { + "id": "5abdfbc3-cc06-477c-95ea-9be582df206b", + "numericId": 48, + "displayOrder": 48, + "tags": [ + "ALB" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the ALB (Application Load Balancer)", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the ALB (Application Load Balancer) can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses" + }, + { + "id": "1d6b6a27-939a-4515-a3ac-dda8cb2cbebe", + "numericId": 47, + "displayOrder": 47, + "tags": [ + "ElasticBeanStalk" + ], + "threatSource": "threat actor", + "prerequisites": "that discovers an Elastic Beanstalk environment in a public subnet", + "threatAction": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor that discovers an Elastic Beanstalk environment in a public subnet can perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "aa4ace87-4350-4e06-b975-2cb9a3dda05a", + "numericId": 46, + "displayOrder": 46, + "tags": [ + "ElasticBeanStalk" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the Elastic Beanstalk environment", + "threatAction": "attempt to take advantage of a known vulnerability in a platform component used by Elastic Beanstalk", + "impactedGoal": [ + "integrity", + "availability", + "confidentiality" + ], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the Elastic Beanstalk environment can attempt to take advantage of a known vulnerability in a platform component used by Elastic Beanstalk, resulting in reduced integrity, availability and/or confidentiality of this application" + }, + { + "id": "5ee158eb-f45c-43af-bfe4-b22bd4a38b8b", + "numericId": 45, + "displayOrder": 45, + "tags": [ + "ElasticBeanStalk" + ], + "threatSource": "threat actor", + "prerequisites": "who is authenticated and authorized", + "threatAction": "deny taking a action that is orchestrated via Elastic Beanstalk environment", + "threatImpact": "lack of knowledge/proof of who took the action", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is authenticated and authorized can deny taking an action that is orchestrated via Elastic Beanstalk environment, which leads to lack of knowledge/proof of who took the action" + }, + { + "id": "f4bd72a6-d939-42c7-9433-6d0d8850abbc", + "numericId": 44, + "displayOrder": 44, + "tags": [ + "ElastiCache" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the ElastiCache Redis cluster listener not configured with IAM authentication", + "threatAction": "perform unauthenticated commands to the cluster", + "threatImpact": "", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the ElastiCache Redis cluster listener not configured with IAM authentication can perform unauthenticated commands to the cluster, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "df2c6877-518f-4d73-97ee-e79c9f0bde84", + "numericId": 43, + "displayOrder": 43, + "tags": [ + "ElastiCache" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the user and the ElastiCache Redis cluster", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the user and the ElastiCache Redis cluster can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses" + }, + { + "id": "18cb5978-912c-4fd8-bae2-9f4339f342b3", + "numericId": 42, + "displayOrder": 42, + "tags": [ + "ElastiCache" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to ElastiCache Redis storage", + "threatAction": "view or modify the contents on the disk", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data within the ElastiCache Redis cluster" + ], + "statement": "A threat actor with physical access to ElastiCache Redis storage can view or modify the contents on the disk, resulting in reduced confidentiality and/or integrity of data within the ElastiCache Redis cluster" + }, + { + "id": "e89e4939-4f14-4fb0-9be2-ce9955dd1a3b", + "numericId": 41, + "displayOrder": 41, + "tags": [ + "ElastiCache" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the ElastiCache cluster listener", + "threatAction": "perform a network probe the database using it's default port", + "threatImpact": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the ElastiCache cluster listener can perform a network probe the database using it's default port, which leads to perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "9162a0f9-b47f-49b9-8422-220ac65697c6", + "numericId": 40, + "displayOrder": 40, + "tags": [ + "ElastiCache" + ], + "threatSource": "external threat actor", + "prerequisites": "", + "threatAction": "discover the ElastiCache cluster that has a public IP address", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application", + "data within the ElastiCache cluster" + ], + "statement": "An external threat actor can discover the ElastiCache cluster that has a public IP address, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application and data within the ElastiCache cluster" + }, + { + "id": "63c13cf9-adcc-4db5-b0a7-e58a455f1190", + "numericId": 39, + "displayOrder": 39, + "tags": [ + "EKS" + ], + "threatSource": "external threat actor", + "prerequisites": "who has discovered a EKS cluster Kubernetes API server endpoint", + "threatAction": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor who has discovered an EKS cluster Kubernetes API server endpoint can perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "b34692af-8e67-46d1-8393-2f5c8264c783", + "numericId": 38, + "displayOrder": 38, + "tags": [ + "EKS" + ], + "threatSource": "threat actor", + "prerequisites": "who is authenticated and authorized", + "threatAction": "deny taking a action that is performed via the EKS control plane", + "threatImpact": "lack of knowledge/proof of who took the action", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is authenticated and authorized can deny taking an action that is performed via the EKS control plane, which leads to lack of knowledge/proof of who took the action" + }, + { + "id": "1fc40b42-ddf8-4632-8584-00d2fe423f8f", + "numericId": 37, + "displayOrder": 37, + "tags": [ + "EFS" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to EFS (Elastic File System) storage", + "threatAction": "view or modify the contents on the disk", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data within the EFS mount" + ], + "statement": "A threat actor with physical access to EFS (Elastic File System) storage can view or modify the contents on the disk, resulting in reduced confidentiality and/or integrity of data within the EFS mount" + }, + { + "id": "dd2bfe1d-f75c-42cb-a2cd-6dfb949318e1", + "numericId": 36, + "displayOrder": 36, + "tags": [ + "ECS" + ], + "threatSource": "actor", + "prerequisites": "that can view the ECS Task Definition", + "threatAction": "can obtain any AWS Access Key and Secret Access Key that may be stored there", + "threatImpact": "the actor being able to take any action that the IAM Principal associated with the keys is able to do", + "impactedAssets": [ + "this application" + ], + "statement": "An actor that can view the ECS Task Definition can can obtain any AWS Access Key and Secret Access Key that may be stored there, which leads to the actor being able to take any action that the IAM Principal associated with the keys is able to do, negatively impacting this application" + }, + { + "id": "61009521-4be1-4bf7-b0cd-ada8401ec7f7", + "numericId": 35, + "displayOrder": 35, + "metadata": [], + "tags": [ + "ECS" + ], + "threatSource": "threat actor", + "prerequisites": "who is authenticated and authorized", + "threatAction": "deny taking a action that is orchestrated via an ECS Task", + "threatImpact": "lack of knowledge/proof of who took the action", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is authenticated and authorized can deny taking an action that is orchestrated via an ECS Task, which leads to lack of knowledge/proof of who took the action" + }, + { + "id": "5f5adfdb-98cf-4580-86bb-42ae5bd2bb7b", + "numericId": 34, + "displayOrder": 34, + "tags": [ + "ECR" + ], + "threatSource": "external threat actor", + "prerequisites": "who as discovered a ECR repository", + "threatAction": "access the container images hosted within the repository", + "threatImpact": "information disclosure that aid in the intrusion activities being successful against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor who as discovered an ECR repository can access the container images hosted within the repository, which leads to information disclosure that aid in the intrusion activities being successful against the exposed attack surface, negatively impacting this application" + }, + { + "id": "310b7a7f-e13c-44a3-bb3a-91ad7bf9ba98", + "numericId": 33, + "displayOrder": 33, + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "threat actor", + "prerequisites": "with established persistence within a host in the VPC", + "threatAction": "go unnoticed for a prolonged period due unnecessary Security Groups being kept as their rationale for existence is not clear", + "statement": "A threat actor with established persistence within a host in the VPC can go unnoticed for a prolonged period due unnecessary Security Groups being kept as their rationale for existence is not clear" + }, + { + "id": "961651aa-830e-4b67-9755-1541d005475b", + "numericId": 32, + "displayOrder": 32, + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "external threat actor", + "threatAction": "discover EC2 instances that have public IP addresses and allow ingress to all internet addresses to SSH, or move laterally to non-public EC2 instances via SSH", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover EC2 instances that have public IP addresses and allow ingress to all internet addresses to SSH, or move laterally to non-public EC2 instances via SSH, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "8c3352e2-b817-4139-9256-81e75ff127f7", + "numericId": 31, + "displayOrder": 31, + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "external threat actor", + "threatAction": "discover EC2 instances that have public IP addresses and allow ingress to all internet addresses, or move laterally to non-public EC2 instances", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover EC2 instances that have public IP addresses and allow ingress to all internet addresses, or move laterally to non-public EC2 instances, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "aadd2e92-221b-4a13-90e2-7f5b41e80709", + "numericId": 30, + "displayOrder": 30, + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to a listener(s) configured on an EC2 instance", + "threatAction": "perform a network probe on common service ports (e.g. 20, 21, 3389, 3309, 3306, 4333)", + "threatImpact": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to a listener(s) configured on an EC2 instance can perform a network probe on common service ports (e.g. 20, 21, 3389, 3309, 3306, 4333), which leads to perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "801739c7-11d2-4bbe-8368-4d49c501e39f", + "numericId": 29, + "displayOrder": 29, + "tags": [ + "EC2" + ], + "threatSource": "threat actor", + "prerequisites": "that has discovered a legacy EC2-Classic instance", + "threatAction": "perform reconnaissance and intrusion activities against the exposed attack surface", + "statement": "A threat actor that has discovered a legacy EC2-Classic instance can perform reconnaissance and intrusion activities against the exposed attack surface" + }, + { + "id": "71e166df-1f57-4f3c-a1af-919180bcdb65", + "numericId": 28, + "displayOrder": 28, + "tags": [ + "EC2" + ], + "threatSource": "external threat actor", + "prerequisites": "with access to an EC2 instance", + "threatAction": "can steal any long-lived AWS credentials (AWS Access Key, AWS Secret Key) being stored on the instance", + "threatImpact": "the actor to take any action that the credentials allowed can do, and can do so from outside of the EC2 instance and until the credentials are manually revoked", + "statement": "An external threat actor with access to an EC2 instance can can steal any long-lived AWS credentials (AWS Access Key, AWS Secret Key) being stored on the instance, which leads to the actor to take any action that the credentials allowed can do, and can do so from outside of the EC2 instance and until the credentials are manually revoked" + }, + { + "id": "9bbb493a-c435-420a-aa35-3fa992064127", + "numericId": 27, + "displayOrder": 27, + "tags": [ + "EBS", + "SSE", + "EC2" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to EBS (Elastic Block Store) storage", + "threatAction": "view or modify the contents on the disk", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data within the EBS volume" + ], + "statement": "A threat actor with physical access to EBS (Elastic Block Store) storage can view or modify the contents on the disk, resulting in reduced confidentiality and/or integrity of data within the EBS volume" + }, + { + "id": "28a2d363-365e-4959-a35c-d51eaf74af5f", + "numericId": 26, + "displayOrder": 26, + "tags": [ + "DAX", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to DAX storage", + "threatAction": "view or modify the contents of the database", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data written to disk by the DAX cluster" + ], + "statement": "A threat actor with physical access to DAX storage can view or modify the contents of the database, resulting in reduced confidentiality and/or integrity of data written to disk by the DAX cluster" + }, + { + "id": "a5fba694-7098-4263-8001-305f13512f3b", + "numericId": 25, + "displayOrder": 25, + "tags": [ + "DocumentDB" + ], + "threatSource": "threat actor", + "prerequisites": "who can view the DocumentDB configuration", + "threatAction": "obtain the username and password for the DocumentDB cluster", + "threatImpact": "the actor being able to access anything the associated DocumentDB user is authorised to do", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who can view the DocumentDB configuration can obtain the username and password for the DocumentDB cluster, which leads to the actor being able to access anything the associated DocumentDB user is authorised to do, negatively impacting this application" + }, + { + "id": "76de4625-b01a-4cf4-8cbb-b5a1a1f75ebf", + "numericId": 24, + "displayOrder": 24, + "tags": [ + "DocumentDB" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the DocumentDB database listener", + "threatAction": "perform a network probe the database using it's default port", + "threatImpact": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the DocumentDB database listener can perform a network probe the database using it's default port, which leads to perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "6e86656c-5779-4695-9a8f-1caa535bb4e9", + "numericId": 23, + "displayOrder": 23, + "tags": [ + "DocumentDB" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to DocumentDB storage", + "threatAction": "view or modify the contents of the database", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data hosted within the database" + ], + "statement": "A threat actor with physical access to DocumentDB storage can view or modify the contents of the database, resulting in reduced confidentiality and/or integrity of data hosted within the database" + }, + { + "id": "9f6177a5-0f9f-408b-b0d1-9e8067b60dc2", + "numericId": 22, + "displayOrder": 22, + "tags": [ + "DMS", + "VPC" + ], + "threatSource": "external threat actor", + "prerequisites": "", + "threatAction": "discover DMS (Database Migration Services) instances that have public IP addresses", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover DMS (Database Migration Services) instances that have public IP addresses, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "eb82eea2-d949-4fd4-b5d2-1516b9c977bb", + "numericId": 21, + "displayOrder": 21, + "tags": [ + "Cognito" + ], + "threatSource": "threat actor", + "prerequisites": "who has discovered an application endpoint with Cognito authenticated logins", + "threatAction": "perform a dictionary or brute force attack to authenticate as an authorized Cognito user", + "threatImpact": "the actor being able to do anything the associated Cognito user is authorised to do", + "impactedGoal": [], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who has discovered an application endpoint with Cognito authenticated logins can perform a dictionary or brute force attack to authenticate as an authorized Cognito user, which leads to the actor being able to do anything the associated Cognito user is authorised to do, negatively impacting this application" + }, + { + "id": "ae94934d-1eda-4be0-befd-1e5c75cda4e2", + "numericId": 20, + "displayOrder": 20, + "tags": [ + "Cognito" + ], + "threatSource": "threat actor", + "prerequisites": "who has discovered an application endpoint with Cognito authenticated logins", + "threatAction": "perform any unauthenticated actions allowed by the Cognito user pool configuration", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who has discovered an application endpoint with Cognito authenticated logins can perform any unauthenticated actions allowed by the Cognito user pool configuration, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "0837eafd-540f-4a08-a602-a577d6dcdbc0", + "numericId": 19, + "displayOrder": 19, + "metadata": [], + "tags": [ + "Cognito" + ], + "threatSource": "threat actor", + "prerequisites": "who is able brute force, or has knowledge of valid Amazon Cognito usernames and passwords", + "threatAction": "spoof an authenticated user", + "threatImpact": "the actor being able to do anything the user can do", + "impactedGoal": [], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who is able brute force, or has knowledge of valid Amazon Cognito usernames and passwords can spoof an authenticated user, which leads to the actor being able to do anything the user can do, negatively impacting this application" + }, + { + "id": "9893d5cc-6cff-4d3e-8bd2-f7c2f4af58f2", + "numericId": 18, + "displayOrder": 18, + "tags": [ + "Cognito" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the API", + "threatAction": "access the API using a method other than Cognito user pool authentication", + "threatImpact": "the actor being able to do anything a authenticated or unauthenticated user is permitted to do", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the API can access the API using a method other than Cognito user pool authentication, which leads to the actor being able to do anything an authenticated or unauthenticated user is permitted to do, negatively impacting this application" + }, + { + "id": "36547ec4-c4d6-487d-8fdf-83cb2975473e", + "numericId": 17, + "displayOrder": 17, + "tags": [ + "Cognito" + ], + "threatSource": "external threat actor", + "prerequisites": "with valid user credentials", + "threatAction": "authenticate as a the valid user from a geo-location not associated with the valid users established baseline", + "threatImpact": "the actor being able to do anything the user can do", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with valid user credentials can authenticate as a the valid user from a geo-location not associated with the valid users established baseline, which leads to the actor being able to do anything the user can do, negatively impacting this application" + }, + { + "id": "3b6b28ec-be93-41c1-b93c-8df4411a821a", + "numericId": 16, + "displayOrder": 16, + "tags": [ + "Cognito" + ], + "threatSource": "external threat actor", + "prerequisites": "with access to a compromised credential list (e.g. purchased from the dark web)", + "threatAction": "perform credential stuffing against a valid Cognito user in the pool that has re-used a password present in the compromised list", + "threatImpact": "the actor being able to do anything the user can do", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with access to a compromised credential list (e.g. purchased from the dark web) can perform credential stuffing against a valid Cognito user in the pool that has re-used a password present in the compromised list, which leads to the actor being able to do anything the user can do, negatively impacting this application" + }, + { + "id": "9d2c9e3b-f5c8-42af-8f63-4bd2309cf0d9", + "numericId": 15, + "displayOrder": 15, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "E", + "D" + ] + } + ], + "tags": [ + "CodeBuild" + ], + "threatSource": "threat actor", + "prerequisites": "who is able to influence what commands are run within a CodeBuild job", + "threatAction": "take run commands supported by 'privilegedMode'", + "threatImpact": "them accessing the Docker API and associated resources", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who is able to influence what commands are run within a CodeBuild job can take run commands supported by 'privilegedMode', which leads to them accessing the Docker API and associated resources, negatively impacting this application" + }, + { + "id": "3e3ee2f1-053d-4e40-8917-52ce4f45ea56", + "numericId": 14, + "displayOrder": 14, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T" + ] + } + ], + "tags": [ + "CodeBuild" + ], + "threatSource": "threat actor", + "prerequisites": "who can trick a user into using a external vulnerable or malicious Docker image in their CodeBuild project", + "threatAction": "tamper with the build process", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who can trick a user into using an external vulnerable or malicious Docker image in their CodeBuild project can tamper with the build process, negatively impacting this application" + }, + { + "id": "7b1dbdd4-2cea-4b16-a15b-51b05822f972", + "numericId": 13, + "displayOrder": 13, + "tags": [ + "CodeBuild" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to CodeBuild storage", + "threatAction": "view or modify build artefacts (e.g. cache, logs, exported raw test report data files, and build results)", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "this application's build artefacts" + ], + "statement": "A threat actor with physical access to CodeBuild storage can view or modify build artefacts (e.g. cache, logs, exported raw test report data files, and build results), resulting in reduced confidentiality and/or integrity of this application's build artefacts" + }, + { + "id": "493365cb-ff0b-411b-bc10-aaa97b6306fa", + "numericId": 12, + "displayOrder": 12, + "tags": [ + "CodeBuild" + ], + "threatSource": "actor", + "prerequisites": "that can view the CodeBuild environment variables", + "threatAction": "can obtain any AWS Access Key and Secret Access Key that may be stored there", + "threatImpact": "the actor being able to take any action that the IAM Principal associated with the keys is able to do", + "impactedAssets": [ + "this application" + ], + "statement": "An actor that can view the CodeBuild environment variables can can obtain any AWS Access Key and Secret Access Key that may be stored there, which leads to the actor being able to take any action that the IAM Principal associated with the keys is able to do, negatively impacting this application" + }, + { + "id": "3baec34a-5ed0-459d-90d9-9e5497e29751", + "numericId": 11, + "displayOrder": 11, + "tags": [ + "CloudFront" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the CloudFront Distribution", + "threatAction": "make arbitrary web requests that are either not explicitly allowed, blocked or counted", + "threatImpact": "them perform reconnaissance and intrusion activities against the content served by the CloudFront Distribution", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the CloudFront Distribution can make arbitrary web requests that are either not explicitly allowed, blocked or counted, which leads to them perform reconnaissance and intrusion activities against the content served by the CloudFront Distribution, negatively impacting this application" + }, + { + "id": "d4378c9b-e680-41c1-8cc2-136e124461dd", + "numericId": 10, + "displayOrder": 10, + "tags": [ + "CloudFront" + ], + "threatSource": "external threat actor", + "threatAction": "bypass the CloudFront Distribution and associated controls (e.g. Geo-blocking)", + "threatImpact": "direct access to static assets hosted on the Amazon S3 Origin", + "impactedAssets": [ + "assets hosted on the S3 Origin for this application" + ], + "statement": "An external threat actor can bypass the CloudFront Distribution and associated controls (e.g. Geo-blocking), which leads to direct access to static assets hosted on the Amazon S3 Origin, negatively impacting assets hosted on the S3 Origin for this application" + }, + { + "id": "c7d756f0-0576-4644-a9b3-afea5bd52a7c", + "numericId": 9, + "displayOrder": 9, + "tags": [ + "CloudFront" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between CloudFront Distribution and the origin", + "threatAction": "take advantage of a vulnerability in an older/depreciated SSL/TLS protocol", + "threatImpact": "them being able manipulate view or modify the content from the origin and served by the CloudFront Distribution", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between CloudFront Distribution and the origin can take advantage of a vulnerability in an older/depreciated SSL/TLS protocol, which leads to them being able manipulate view or modify the content from the origin and served by the CloudFront Distribution" + }, + { + "id": "8cde9550-4aac-4792-851f-e6ac01b3ae92", + "numericId": 8, + "displayOrder": 8, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T", + "I" + ] + } + ], + "tags": [ + "CloudFront" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the user and the CloudFront Distribution", + "threatAction": "take advantage of a vulnerability in an older/depreciated SSL/TLS protocol", + "threatImpact": "them being able manipulate view or modify the content served by the CloudFront Distribution", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the user and the CloudFront Distribution can take advantage of a vulnerability in an older/depreciated SSL/TLS protocol, which leads to them being able manipulate view or modify the content served by the CloudFront Distribution" + }, + { + "id": "8c9cd385-7a3d-486d-90fc-5b9f3b28a04a", + "numericId": 7, + "displayOrder": 7, + "tags": [ + "CloudFront" + ], + "threatSource": "external threat actor", + "threatAction": "discover application web assets that are exposed via CloudFront distributions", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover application web assets that are exposed via CloudFront distributions, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "c40381b0-0bdf-4e2a-86ba-966634fab370", + "numericId": 6, + "displayOrder": 6, + "tags": [ + "Cloud9", + "EC2", + "VPC" + ], + "threatSource": "external threat actor", + "prerequisites": "", + "threatAction": "discover Cloud9 EC2 instances that have public IP addresses and that are exposing SSH", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover Cloud9 EC2 instances that have public IP addresses and that are exposing SSH, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "82ffe16c-520c-420e-aa68-d1e9562acc5d", + "numericId": 5, + "displayOrder": 5, + "metadata": [], + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "external threat actor", + "prerequisites": "", + "threatAction": "discover EC2 instances that have public IP addresses", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover EC2 instances that have public IP addresses, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "4395c4e3-db64-44c0-8be0-0bcffad7f752", + "numericId": 4, + "displayOrder": 4, + "metadata": [], + "tags": [ + "Athena" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to Amazon S3 bucket used for Athena workgroup storage", + "threatAction": "view the results of Athena queries", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's Athena queries" + ], + "statement": "A threat actor with physical access to Amazon S3 bucket used for Athena workgroup storage can view the results of Athena queries, resulting in reduced confidentiality of this application's Athena queries" + }, + { + "id": "813c3fc1-33bc-4823-9f9c-91b2df1f4030", + "numericId": 3, + "displayOrder": 3, + "metadata": [], + "tags": [ + "API Gateway" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to, and authorization to use the API", + "threatAction": "can supply unexpected HTTP headers or JSON payload to the API", + "threatImpact": "the application behaving in unintended ways", + "impactedGoal": [], + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to, and authorization to use the API can can supply unexpected HTTP headers or JSON payload to the API, which leads to the application behaving in unintended ways, negatively impacting this application" + }, + { + "id": "2d370353-bc79-43a7-8e92-68d0850a13d0", + "numericId": 2, + "displayOrder": 2, + "metadata": [], + "tags": [ + "API Gateway" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the API", + "threatAction": "make unauthenticated calls to the API", + "threatImpact": "", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the API can make unauthenticated calls to the API, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "dc429030-4063-43db-96ea-d60b8ab83152", + "numericId": 1, + "displayOrder": 1, + "metadata": [], + "tags": [ + "API Gateway" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the API", + "threatAction": "make arbitrary web requests that are either not explicitly allowed, blocked or counted", + "threatImpact": "them perform reconnaissance and intrusion activities against the API", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the API can make arbitrary web requests that are either not explicitly allowed, blocked or counted, which leads to them perform reconnaissance and intrusion activities against the API, negatively impacting this application" + } + ] +} \ No newline at end of file diff --git a/packages/cdk-graph-plugin-threat-composer/src/model-generator/threat-model-generator.ts b/packages/cdk-graph-plugin-threat-composer/src/model-generator/threat-model-generator.ts new file mode 100644 index 000000000..71480fba0 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/src/model-generator/threat-model-generator.ts @@ -0,0 +1,241 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import { ExtendedNagResult, NagResultCompliance } from "@aws/pdk-nag"; +import { orderBy, uniq } from "lodash"; +import * as BASE_THREAT_MODEL from "./base-model/threat-composer-base-model.tc.json"; +import { ThreatComposerApplicationDetails } from "./types"; + +type ThreatComposerModel = typeof BASE_THREAT_MODEL; +type ThreatComposerThreat = ThreatComposerModel["threats"][number]; +type ThreatComposerMitigation = ThreatComposerModel["mitigations"][number]; + +interface ComplianceFindings { + readonly compliantResources: Set; + readonly nonCompliantResources: Set; +} + +// Mitigation content is the CDK Nag rule name. +const NAG_RULE_MITIGATION_PREFIX = "cdk-nag rule: "; + +/** + * Options for generating a Threat Composer threat model + */ +export interface ThreatModelGeneratorOptions { + /** + * Details about the application to include in the threat model + */ + readonly applicationDetails?: ThreatComposerApplicationDetails; + /** + * A data uri for an architecture diagram image + */ + readonly architectureImageDataUri?: string; +} + +/** + * Generates Threat Composer threat models based on CDK Nag results + */ +export class ThreatModelGenerator { + /** + * Given a Threat Composer mitigation, return the CDK Nag rule associated (if any) + */ + private getRuleFromMitigation = ( + mitigation?: ThreatComposerMitigation + ): string | undefined => { + if (mitigation?.content.startsWith(NAG_RULE_MITIGATION_PREFIX)) { + return mitigation.content.split(NAG_RULE_MITIGATION_PREFIX)[1] as + | string + | undefined; + } + return undefined; + }; + + /** + * Deduplicate suppression reasons, removing resource details if present + */ + private prettySuppressions = (suppressions: string[]): string[] => { + return uniq( + suppressions.map((s) => + s.startsWith("[") ? s.slice(s.indexOf("] ") + 2) : s + ) + ); + }; + + /** + * Generate a threat model from a set of cdk nag results + */ + public generate( + results: ExtendedNagResult[], + options?: ThreatModelGeneratorOptions + ): ThreatComposerModel { + // Summarise nag results into rules and the counts of resources compliant/non-compliant + const allApplicableRules = new Set(); + const compliance: { [nagRule: string]: ComplianceFindings } = {}; + const suppressionReasons: { [nagRule: string]: string[] } = {}; + + for (const result of results) { + const rule = result.ruleOriginalName; + + if (!compliance[rule]) { + compliance[rule] = { + compliantResources: new Set(), + nonCompliantResources: new Set(), + }; + } + + // Add to the set of all applicable rules so long as the rule is applicable + if (result.compliance !== NagResultCompliance.NOT_APPLICABLE) { + allApplicableRules.add(rule); + } + + if ( + [ + NagResultCompliance.NON_COMPLIANT, + NagResultCompliance.ERROR, + NagResultCompliance.NON_COMPLIANT_SUPPRESSED, + NagResultCompliance.ERROR_SUPPRESSED, + ].includes(result.compliance) + ) { + // Add the resource path to the compliance set + compliance[rule].nonCompliantResources.add(result.resource.node.path); + if (result.suppressionReason) { + suppressionReasons[rule] = [ + ...(suppressionReasons[rule] ?? []), + result.suppressionReason, + ]; + } + } else if (result.compliance === NagResultCompliance.COMPLIANT) { + // Resource is compliant + compliance[rule].compliantResources.add(result.resource.node.path); + } + } + + const mitigationsById = Object.fromEntries( + BASE_THREAT_MODEL.mitigations.map((m) => [m.id, m]) + ); + const threatIdToMitigationIds = BASE_THREAT_MODEL.mitigationLinks.reduce( + (byId, m) => ({ + ...byId, + [m.linkedId]: [...(byId[m.linkedId] ?? []), m.mitigationId], + }), + {} as { [threatId: string]: string[] } + ); + + // Get applicable threats - ie threats where there is a mitigation which is a CDK nag rule that is applicable to this project + const threats: ThreatComposerThreat[] = orderBy( + BASE_THREAT_MODEL.threats, + "numericId" + ) + .filter((threat) => { + const mitigationIds = threatIdToMitigationIds[threat.id] ?? []; + return mitigationIds.find((id) => { + const mitigationRule = this.getRuleFromMitigation( + mitigationsById[id] + ); + return mitigationRule && allApplicableRules.has(mitigationRule); + }); + }) + .map((t, i) => ({ + ...t, + // Re-map numeric ids and display order + numericId: i + 1, + displayOrder: i + 1, + })); + + // Get applicable mitigations + const mitigations = ( + orderBy(BASE_THREAT_MODEL.mitigations, "numericId") + .map((m) => { + const mitigationRule = this.getRuleFromMitigation( + mitigationsById[m.id] + ); + if (mitigationRule && compliance[mitigationRule]) { + const { compliantResources, nonCompliantResources } = + compliance[mitigationRule]; + const suppressions = suppressionReasons[mitigationRule]; + const compliant = compliantResources.size; + const nonCompliant = nonCompliantResources.size; + + // We can't really warrant adding a mitigation when 0 resources are compliant and there are no suppression reasons + if ( + compliant === 0 && + (!suppressions || suppressions.length === 0) + ) { + return undefined; + } + + const suppressionComment = suppressions + ? `\n\n__Suppression Reasons__:\n${this.prettySuppressions( + suppressions + ) + .map((reason) => `* ${reason}`) + .join("\n")}` + : ""; + + let comment = `${compliant} of ${ + compliant + nonCompliant + } Resources Compliant.${suppressionComment}`; + + // Threat composer limits comments to 1000 chars + if (comment.length > 1000) { + comment = comment.slice(0, 997) + "..."; + } + + return { + ...m, + metadata: [ + // TODO: Consider appending to existing comments rather than overriding + { + key: "Comments", + value: comment, + }, + ], + }; + } + return undefined; + }) + .filter((x) => x) as ThreatComposerMitigation[] + ).map((m, i) => ({ + ...m, + // Re-map numeric ids and display order + numericId: i + 1, + displayOrder: i + 1, + })); + + // Include only mitigation links where we have threats and mitigations + const projectThreatIds = new Set(threats.map(({ id }) => id)); + const projectMitigationIds = new Set(mitigations.map(({ id }) => id)); + const mitigationLinks = BASE_THREAT_MODEL.mitigationLinks.filter( + (link) => + projectThreatIds.has(link.linkedId) && + projectMitigationIds.has(link.mitigationId) + ); + + const threatModel = { + ...BASE_THREAT_MODEL, + threats, + mitigations, + mitigationLinks, + architecture: { + ...BASE_THREAT_MODEL.architecture, + image: options?.architectureImageDataUri ?? "", + }, + applicationInfo: { + ...BASE_THREAT_MODEL.applicationInfo, + name: + options?.applicationDetails?.name ?? + BASE_THREAT_MODEL.applicationInfo.name, + description: + options?.applicationDetails?.description ?? + BASE_THREAT_MODEL.applicationInfo.description, + }, + }; + + // jest interprets the "import * as" import differently, so we remove this to ensure the snapshot + // is more realistic + if ("default" in threatModel) { + delete threatModel.default; + } + + return threatModel; + } +} diff --git a/packages/cdk-graph-plugin-threat-composer/src/model-generator/types.ts b/packages/cdk-graph-plugin-threat-composer/src/model-generator/types.ts new file mode 100644 index 000000000..e16ecbe8d --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/src/model-generator/types.ts @@ -0,0 +1,17 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ + +/** + * Details about the application to include in the threat model + */ +export interface ThreatComposerApplicationDetails { + /** + * The name of the application + * @default "My Application" + */ + readonly name?: string; + /** + * A description of the application + */ + readonly description?: string; +} diff --git a/packages/cdk-graph-plugin-threat-composer/src/plugin.ts b/packages/cdk-graph-plugin-threat-composer/src/plugin.ts new file mode 100644 index 000000000..704347add --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/src/plugin.ts @@ -0,0 +1,124 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as fs from "fs"; +import { + CdkGraph, + CdkGraphArtifact, + CdkGraphContext, + ICdkGraphPlugin, + IGraphPluginBindCallback, + IGraphReportCallback, +} from "@aws/cdk-graph"; +import { PDKNagApp } from "@aws/pdk-nag"; +import { ThreatModelGenerator } from "./model-generator/threat-model-generator"; +import { ThreatComposerApplicationDetails } from "./model-generator/types"; + +/** + * Options for the Threat Composer CDK Graph plugin + */ +export interface CdkGraphThreatComposerPluginOptions { + /** + * Details about the application to include in the threat model + */ + readonly applicationDetails?: ThreatComposerApplicationDetails; +} + +/** + * CdkGraphThreatComposerPlugin is a {@link ICdkGraphPlugin CdkGraph Plugin} implementation for generating + * Threat Composer threat models. + * @see https://github.com/awslabs/threat-composer + */ +export class CdkGraphThreatComposerPlugin implements ICdkGraphPlugin { + /** + * Fixed ID of the threat-composer plugin + */ + static readonly ID = "threat-composer"; + + /** + * Curent semantic version of the threat-composer plugin + */ + static readonly VERSION = "0.0.0"; + + /** @inheritdoc */ + get id(): string { + return CdkGraphThreatComposerPlugin.ID; + } + + /** @inheritdoc */ + get version(): string { + return CdkGraphThreatComposerPlugin.VERSION; + } + + /** + * Retrieve the threat model artifact + */ + get threatModelArtifact(): CdkGraphArtifact | undefined { + return this._threatModelArtifact; + } + + // TODO: consider graph plugin as dependency? + /** @inheritdoc */ + readonly dependencies?: string[] = []; + + /** @internal */ + private _app?: PDKNagApp; + + /** @internal */ + private _options?: CdkGraphThreatComposerPluginOptions; + + /** @internal */ + private _threatModelArtifact: CdkGraphArtifact | undefined = undefined; + + constructor(options?: CdkGraphThreatComposerPluginOptions) { + this._options = options; + } + + /** @inheritdoc */ + bind: IGraphPluginBindCallback = (graph: CdkGraph): void => { + // Validate the top level node is a PDKNagApp, providing us with access to nag results + if (!("extendedNagResults" in graph.root)) { + throw new Error( + `Threat Composer plugin requires the root CDK construct to be a PDKNagApp` + ); + } + this._app = graph.root as PDKNagApp; + }; + + /** @inheritdoc */ + report?: IGraphReportCallback = async ( + context: CdkGraphContext + ): Promise => { + if (!this._app) { + throw new Error("Plugin has not been bound"); + } + + let architectureImageDataUri: string | undefined = undefined; + + const architectureDiagramArtifact: CdkGraphArtifact | undefined = + context.artifacts.DIAGRAM_PNG; + if (architectureDiagramArtifact) { + const diagramBinaryContent = fs.readFileSync( + architectureDiagramArtifact.filepath + ); + architectureImageDataUri = `data:image/png;base64,${diagramBinaryContent.toString( + "base64" + )}`; + } + + const threatModel = new ThreatModelGenerator().generate( + this._app.extendedNagResults(), + { + ...this._options, + architectureImageDataUri, + } + ); + + this._threatModelArtifact = context.writeArtifact( + this, + "THREAT_MODEL", + "threat-model.tc.json", + JSON.stringify(threatModel, null, 2), + "Threat Composer threat model." + ); + }; +} diff --git a/packages/cdk-graph-plugin-threat-composer/test/__snapshots__/plugin-integ.test.ts.snap b/packages/cdk-graph-plugin-threat-composer/test/__snapshots__/plugin-integ.test.ts.snap new file mode 100644 index 000000000..57a9c45ca --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/test/__snapshots__/plugin-integ.test.ts.snap @@ -0,0 +1,796 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`plugin-integ pipeline should generate a threat model 1`] = ` +"{ + "schema": 1, + "applicationInfo": { + "name": "My Application", + "description": "**Important**: This threat model is not comprehensive or complete. This document does not list all possible threats, and where threats do have mapped mitigations - these mitigations are not deemed to be complete.\\n\\nConsider this as a starting point for your own diligence and threat modeling." + }, + "architecture": { + "image": "", + "description": "" + }, + "dataflow": { + "image": "", + "description": "**Note:** A data flow diagram has not been captured at this stage. You should consider creating a data-flow diagram." + }, + "assumptions": [], + "mitigations": [ + { + "id": "89a72e46-d073-4207-bd5a-23636c9a29e6", + "numericId": 1, + "displayOrder": 1, + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionNoOutdatedSSL", + "metadata": [ + { + "key": "Comments", + "value": "2 of 2 Resources Compliant." + } + ] + }, + { + "id": "41220750-87bd-4c85-94f1-999746809166", + "numericId": 2, + "displayOrder": 2, + "tags": [ + "CloudFront" + ], + "content": "cdk-nag rule: CloudFrontDistributionS3OriginAccessIdentity", + "metadata": [ + { + "key": "Comments", + "value": "2 of 2 Resources Compliant." + } + ] + }, + { + "id": "64a10a2f-8f11-4e98-8d08-8675853b9fef", + "numericId": 3, + "displayOrder": 3, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectKMSEncryptedArtifacts", + "metadata": [ + { + "key": "Comments", + "value": "3 of 3 Resources Compliant." + } + ] + }, + { + "id": "ea70a6ca-3fa7-403b-87fc-80e4da6bce1e", + "numericId": 4, + "displayOrder": 4, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectManagedImages", + "metadata": [ + { + "key": "Comments", + "value": "3 of 3 Resources Compliant." + } + ] + }, + { + "id": "c84d3721-1539-444a-af67-bd2fed80735f", + "numericId": 5, + "displayOrder": 5, + "tags": [ + "CodeBuild" + ], + "content": "cdk-nag rule: CodeBuildProjectPrivilegedModeDisabled", + "metadata": [ + { + "key": "Comments", + "value": "3 of 3 Resources Compliant." + } + ] + }, + { + "id": "0edef48e-478a-4354-afba-04cbd8a678af", + "numericId": 6, + "displayOrder": 6, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2RestrictedInbound", + "metadata": [ + { + "key": "Comments", + "value": "4 of 6 Resources Compliant." + } + ] + }, + { + "id": "a3adc4bc-12e6-4e51-9a3b-f70173626aed", + "numericId": 7, + "displayOrder": 7, + "tags": [ + "EC2", + "VPC" + ], + "content": "cdk-nag rule: EC2SecurityGroupDescription", + "metadata": [ + { + "key": "Comments", + "value": "6 of 6 Resources Compliant." + } + ] + }, + { + "id": "da85ab97-eb06-4c15-9782-5a7a1924c7d4", + "numericId": 8, + "displayOrder": 8, + "tags": [ + "IAM" + ], + "content": "cdk-nag rule: IAMNoManagedPolicies", + "metadata": [ + { + "key": "Comments", + "value": "15 of 33 Resources Compliant." + } + ] + }, + { + "id": "ca417660-79a6-4725-b498-7406ffc8a9f5", + "numericId": 9, + "displayOrder": 9, + "tags": [ + "IAM" + ], + "content": "cdk-nag rule: IAMNoWildcardPermissions", + "metadata": [ + { + "key": "Comments", + "value": "29 of 48 Resources Compliant.\\n\\n__Suppression Reasons__:\\n* Wildcards are needed for dynamically created resources." + } + ] + }, + { + "id": "9cd8dfd8-8f1f-4697-aa2d-17378c3eb587", + "numericId": 10, + "displayOrder": 10, + "tags": [ + "KMS" + ], + "content": "cdk-nag rule: KMSBackingKeyRotationEnabled", + "metadata": [ + { + "key": "Comments", + "value": "1 of 1 Resources Compliant." + } + ] + }, + { + "id": "fcd9742a-30eb-4303-97e7-206e4a1f63fd", + "numericId": 11, + "displayOrder": 11, + "tags": [ + "Lambda" + ], + "content": "cdk-nag rule: LambdaLatestVersion", + "metadata": [ + { + "key": "Comments", + "value": "8 of 14 Resources Compliant." + } + ] + }, + { + "id": "0ae5ca12-88c7-4648-a1e8-28ad585c3336", + "numericId": 12, + "displayOrder": 12, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketLevelPublicAccessProhibited", + "metadata": [ + { + "key": "Comments", + "value": "6 of 6 Resources Compliant." + } + ] + }, + { + "id": "646feb9c-6f18-4307-8a90-8a44b851d176", + "numericId": 13, + "displayOrder": 13, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketLoggingEnabled", + "metadata": [ + { + "key": "Comments", + "value": "2 of 6 Resources Compliant." + } + ] + }, + { + "id": "b19fd780-64a3-42c6-a0d2-92833af17e40", + "numericId": 14, + "displayOrder": 14, + "tags": [ + "S3" + ], + "content": "cdk-nag rule: S3BucketSSLRequestsOnly", + "metadata": [ + { + "key": "Comments", + "value": "4 of 8 Resources Compliant." + } + ] + }, + { + "id": "c0f8d761-b616-49d4-b60e-d9d413c91f19", + "numericId": 15, + "displayOrder": 15, + "tags": [ + "S3", + "CloudFront" + ], + "content": "cdk-nag rule: S3WebBucketOAIAccess", + "metadata": [ + { + "key": "Comments", + "value": "6 of 6 Resources Compliant." + } + ] + } + ], + "assumptionLinks": [], + "mitigationLinks": [ + { + "mitigationId": "89a72e46-d073-4207-bd5a-23636c9a29e6", + "linkedId": "c7d756f0-0576-4644-a9b3-afea5bd52a7c" + }, + { + "mitigationId": "41220750-87bd-4c85-94f1-999746809166", + "linkedId": "d4378c9b-e680-41c1-8cc2-136e124461dd" + }, + { + "mitigationId": "64a10a2f-8f11-4e98-8d08-8675853b9fef", + "linkedId": "7b1dbdd4-2cea-4b16-a15b-51b05822f972" + }, + { + "mitigationId": "ea70a6ca-3fa7-403b-87fc-80e4da6bce1e", + "linkedId": "3e3ee2f1-053d-4e40-8917-52ce4f45ea56" + }, + { + "mitigationId": "c84d3721-1539-444a-af67-bd2fed80735f", + "linkedId": "9d2c9e3b-f5c8-42af-8f63-4bd2309cf0d9" + }, + { + "mitigationId": "0edef48e-478a-4354-afba-04cbd8a678af", + "linkedId": "8c3352e2-b817-4139-9256-81e75ff127f7" + }, + { + "mitigationId": "a3adc4bc-12e6-4e51-9a3b-f70173626aed", + "linkedId": "310b7a7f-e13c-44a3-bb3a-91ad7bf9ba98" + }, + { + "mitigationId": "da85ab97-eb06-4c15-9782-5a7a1924c7d4", + "linkedId": "1c62b52e-f3ba-4968-a14d-745691b706f6" + }, + { + "mitigationId": "ca417660-79a6-4725-b498-7406ffc8a9f5", + "linkedId": "1c62b52e-f3ba-4968-a14d-745691b706f6" + }, + { + "mitigationId": "fcd9742a-30eb-4303-97e7-206e4a1f63fd", + "linkedId": "5d521ccc-ca9c-4790-b045-0a1e26de9aa0" + }, + { + "mitigationId": "0ae5ca12-88c7-4648-a1e8-28ad585c3336", + "linkedId": "8c383856-988d-45a4-bc92-5c9aab42aab3" + }, + { + "mitigationId": "646feb9c-6f18-4307-8a90-8a44b851d176", + "linkedId": "1b240cb7-3557-41e7-9c19-21ebc73ad0ec" + }, + { + "mitigationId": "b19fd780-64a3-42c6-a0d2-92833af17e40", + "linkedId": "77e519f0-641e-4b99-96a3-db0130381c97" + }, + { + "mitigationId": "c0f8d761-b616-49d4-b60e-d9d413c91f19", + "linkedId": "cc8b9fcb-dd2a-41ad-a4f1-11e93ae0b031" + } + ], + "threats": [ + { + "id": "dc429030-4063-43db-96ea-d60b8ab83152", + "numericId": 1, + "displayOrder": 1, + "metadata": [], + "tags": [ + "API Gateway" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the API", + "threatAction": "make arbitrary web requests that are either not explicitly allowed, blocked or counted", + "threatImpact": "them perform reconnaissance and intrusion activities against the API", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the API can make arbitrary web requests that are either not explicitly allowed, blocked or counted, which leads to them perform reconnaissance and intrusion activities against the API, negatively impacting this application" + }, + { + "id": "2d370353-bc79-43a7-8e92-68d0850a13d0", + "numericId": 2, + "displayOrder": 2, + "metadata": [], + "tags": [ + "API Gateway" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the API", + "threatAction": "make unauthenticated calls to the API", + "threatImpact": "", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the API can make unauthenticated calls to the API, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "813c3fc1-33bc-4823-9f9c-91b2df1f4030", + "numericId": 3, + "displayOrder": 3, + "metadata": [], + "tags": [ + "API Gateway" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to, and authorization to use the API", + "threatAction": "can supply unexpected HTTP headers or JSON payload to the API", + "threatImpact": "the application behaving in unintended ways", + "impactedGoal": [], + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to, and authorization to use the API can can supply unexpected HTTP headers or JSON payload to the API, which leads to the application behaving in unintended ways, negatively impacting this application" + }, + { + "id": "8c9cd385-7a3d-486d-90fc-5b9f3b28a04a", + "numericId": 4, + "displayOrder": 4, + "tags": [ + "CloudFront" + ], + "threatSource": "external threat actor", + "threatAction": "discover application web assets that are exposed via CloudFront distributions", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover application web assets that are exposed via CloudFront distributions, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "8cde9550-4aac-4792-851f-e6ac01b3ae92", + "numericId": 5, + "displayOrder": 5, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T", + "I" + ] + } + ], + "tags": [ + "CloudFront" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the user and the CloudFront Distribution", + "threatAction": "take advantage of a vulnerability in an older/depreciated SSL/TLS protocol", + "threatImpact": "them being able manipulate view or modify the content served by the CloudFront Distribution", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between the user and the CloudFront Distribution can take advantage of a vulnerability in an older/depreciated SSL/TLS protocol, which leads to them being able manipulate view or modify the content served by the CloudFront Distribution" + }, + { + "id": "c7d756f0-0576-4644-a9b3-afea5bd52a7c", + "numericId": 6, + "displayOrder": 6, + "tags": [ + "CloudFront" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between CloudFront Distribution and the origin", + "threatAction": "take advantage of a vulnerability in an older/depreciated SSL/TLS protocol", + "threatImpact": "them being able manipulate view or modify the content from the origin and served by the CloudFront Distribution", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is in a person-in-the-middle position between CloudFront Distribution and the origin can take advantage of a vulnerability in an older/depreciated SSL/TLS protocol, which leads to them being able manipulate view or modify the content from the origin and served by the CloudFront Distribution" + }, + { + "id": "d4378c9b-e680-41c1-8cc2-136e124461dd", + "numericId": 7, + "displayOrder": 7, + "tags": [ + "CloudFront" + ], + "threatSource": "external threat actor", + "threatAction": "bypass the CloudFront Distribution and associated controls (e.g. Geo-blocking)", + "threatImpact": "direct access to static assets hosted on the Amazon S3 Origin", + "impactedAssets": [ + "assets hosted on the S3 Origin for this application" + ], + "statement": "An external threat actor can bypass the CloudFront Distribution and associated controls (e.g. Geo-blocking), which leads to direct access to static assets hosted on the Amazon S3 Origin, negatively impacting assets hosted on the S3 Origin for this application" + }, + { + "id": "3baec34a-5ed0-459d-90d9-9e5497e29751", + "numericId": 8, + "displayOrder": 8, + "tags": [ + "CloudFront" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the CloudFront Distribution", + "threatAction": "make arbitrary web requests that are either not explicitly allowed, blocked or counted", + "threatImpact": "them perform reconnaissance and intrusion activities against the content served by the CloudFront Distribution", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the CloudFront Distribution can make arbitrary web requests that are either not explicitly allowed, blocked or counted, which leads to them perform reconnaissance and intrusion activities against the content served by the CloudFront Distribution, negatively impacting this application" + }, + { + "id": "7b1dbdd4-2cea-4b16-a15b-51b05822f972", + "numericId": 9, + "displayOrder": 9, + "tags": [ + "CodeBuild" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to CodeBuild storage", + "threatAction": "view or modify build artefacts (e.g. cache, logs, exported raw test report data files, and build results)", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "this application's build artefacts" + ], + "statement": "A threat actor with physical access to CodeBuild storage can view or modify build artefacts (e.g. cache, logs, exported raw test report data files, and build results), resulting in reduced confidentiality and/or integrity of this application's build artefacts" + }, + { + "id": "3e3ee2f1-053d-4e40-8917-52ce4f45ea56", + "numericId": 10, + "displayOrder": 10, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T" + ] + } + ], + "tags": [ + "CodeBuild" + ], + "threatSource": "threat actor", + "prerequisites": "who can trick a user into using a external vulnerable or malicious Docker image in their CodeBuild project", + "threatAction": "tamper with the build process", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who can trick a user into using an external vulnerable or malicious Docker image in their CodeBuild project can tamper with the build process, negatively impacting this application" + }, + { + "id": "9d2c9e3b-f5c8-42af-8f63-4bd2309cf0d9", + "numericId": 11, + "displayOrder": 11, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "E", + "D" + ] + } + ], + "tags": [ + "CodeBuild" + ], + "threatSource": "threat actor", + "prerequisites": "who is able to influence what commands are run within a CodeBuild job", + "threatAction": "take run commands supported by 'privilegedMode'", + "threatImpact": "them accessing the Docker API and associated resources", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who is able to influence what commands are run within a CodeBuild job can take run commands supported by 'privilegedMode', which leads to them accessing the Docker API and associated resources, negatively impacting this application" + }, + { + "id": "9893d5cc-6cff-4d3e-8bd2-f7c2f4af58f2", + "numericId": 12, + "displayOrder": 12, + "tags": [ + "Cognito" + ], + "threatSource": "external threat actor", + "prerequisites": "with a network path to the API", + "threatAction": "access the API using a method other than Cognito user pool authentication", + "threatImpact": "the actor being able to do anything a authenticated or unauthenticated user is permitted to do", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor with a network path to the API can access the API using a method other than Cognito user pool authentication, which leads to the actor being able to do anything an authenticated or unauthenticated user is permitted to do, negatively impacting this application" + }, + { + "id": "9bbb493a-c435-420a-aa35-3fa992064127", + "numericId": 13, + "displayOrder": 13, + "tags": [ + "EBS", + "SSE", + "EC2" + ], + "threatSource": "threat actor", + "prerequisites": "with physical access to EBS (Elastic Block Store) storage", + "threatAction": "view or modify the contents on the disk", + "impactedGoal": [ + "confidentiality", + "integrity" + ], + "impactedAssets": [ + "data within the EBS volume" + ], + "statement": "A threat actor with physical access to EBS (Elastic Block Store) storage can view or modify the contents on the disk, resulting in reduced confidentiality and/or integrity of data within the EBS volume" + }, + { + "id": "8c3352e2-b817-4139-9256-81e75ff127f7", + "numericId": 14, + "displayOrder": 14, + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "external threat actor", + "threatAction": "discover EC2 instances that have public IP addresses and allow ingress to all internet addresses, or move laterally to non-public EC2 instances", + "threatImpact": "reconnaissance and intrusion activities being performed against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "An external threat actor can discover EC2 instances that have public IP addresses and allow ingress to all internet addresses, or move laterally to non-public EC2 instances, which leads to reconnaissance and intrusion activities being performed against the exposed attack surface, negatively impacting this application" + }, + { + "id": "310b7a7f-e13c-44a3-bb3a-91ad7bf9ba98", + "numericId": 15, + "displayOrder": 15, + "tags": [ + "EC2", + "VPC" + ], + "threatSource": "threat actor", + "prerequisites": "with established persistence within a host in the VPC", + "threatAction": "go unnoticed for a prolonged period due unnecessary Security Groups being kept as their rationale for existence is not clear", + "statement": "A threat actor with established persistence within a host in the VPC can go unnoticed for a prolonged period due unnecessary Security Groups being kept as their rationale for existence is not clear" + }, + { + "id": "1c62b52e-f3ba-4968-a14d-745691b706f6", + "numericId": 16, + "displayOrder": 16, + "tags": [ + "IAM" + ], + "threatSource": "threat actor", + "prerequisites": "with access to a valid IAM Principal", + "threatAction": "take advantage of unnecessary permissions included in the associated IAM Policy", + "threatImpact": "the actor being able to do anything the user can do", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with access to a valid IAM Principal can take advantage of unnecessary permissions included in the associated IAM Policy, which leads to the actor being able to do anything the user can do, negatively impacting this application" + }, + { + "id": "5d521ccc-ca9c-4790-b045-0a1e26de9aa0", + "numericId": 17, + "displayOrder": 17, + "tags": [ + "Lambda", + "Vuln Management" + ], + "threatSource": "threat actor", + "prerequisites": "with the ability to invoke or interact with a Lambda function", + "threatAction": "take advantage of a disclosed vulnerability within the runtime version used for a non-container based Lambda function", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with the ability to invoke or interact with a Lambda function can take advantage of a disclosed vulnerability within the runtime version used for a non-container based Lambda function, resulting in reduced confidentiality, integrity and/or availability of this application" + }, + { + "id": "ef634b32-084b-42f6-ae5c-4e65b3953ba5", + "numericId": 18, + "displayOrder": 18, + "tags": [ + "RDS", + "Network Access" + ], + "threatSource": "threat actor", + "prerequisites": "with a network path to the RDS cluster listener", + "threatAction": "perform a network probe the database using it's default port", + "threatImpact": "perform reconnaissance and intrusion activities against the exposed attack surface", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor with a network path to the RDS cluster listener can perform a network probe the database using it's default port, which leads to perform reconnaissance and intrusion activities against the exposed attack surface, negatively impacting this application" + }, + { + "id": "172ce9d2-8159-4c70-a2b7-70dc846bdf70", + "numericId": 19, + "displayOrder": 19, + "tags": [ + "RDS", + "SSE" + ], + "threatSource": "threat actor", + "prerequisites": "with access to underlying storage used for the RDS cluster", + "threatAction": "view the contents of the database", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor with access to underlying storage used for the RDS cluster can view the contents of the database, resulting in reduced confidentiality of this application's data" + }, + { + "id": "8c383856-988d-45a4-bc92-5c9aab42aab3", + "numericId": 20, + "displayOrder": 20, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "T", + "I" + ] + } + ], + "tags": [ + "S3", + "Public Access" + ], + "threatSource": "threat actor", + "prerequisites": "who has discovered a S3 bucket configured for public read or write", + "threatAction": "read or write data to or from the S3 bucket", + "impactedGoal": [ + "confidentiality", + "integrity", + "availability" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who has discovered a S3 bucket configured for public read or write can read or write data to or from the S3 bucket, resulting in reduced confidentiality, integrity and/or availability of this application's data" + }, + { + "id": "1b240cb7-3557-41e7-9c19-21ebc73ad0ec", + "numericId": 21, + "displayOrder": 21, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "R" + ] + } + ], + "tags": [ + "S3", + "Repudiation" + ], + "threatSource": "threat actor", + "prerequisites": "who is authenticated and authorized", + "threatAction": "deny taking a action associated with an Amazon S3 bucket", + "threatImpact": "lack of knowledge/proof of who took the action", + "impactedGoal": [], + "impactedAssets": [], + "statement": "A threat actor who is authenticated and authorized can deny taking an action associated with an Amazon S3 bucket, which leads to lack of knowledge/proof of who took the action" + }, + { + "id": "77e519f0-641e-4b99-96a3-db0130381c97", + "numericId": 22, + "displayOrder": 22, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I", + "T" + ] + } + ], + "tags": [ + "S3", + "MiTM" + ], + "threatSource": "threat actor", + "prerequisites": "who is in a person-in-the-middle position between the client and the Amazon S3 bucket endpoint", + "threatAction": "view plaintext requests and responses", + "threatImpact": "them being able manipulate view or modify the requests or responses", + "impactedGoal": [], + "impactedAssets": [ + "this application's data" + ], + "statement": "A threat actor who is in a person-in-the-middle position between the client and the Amazon S3 bucket endpoint can view plaintext requests and responses, which leads to them being able manipulate view or modify the requests or responses, negatively impacting this application's data" + }, + { + "id": "cc8b9fcb-dd2a-41ad-a4f1-11e93ae0b031", + "numericId": 23, + "displayOrder": 23, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "I" + ] + } + ], + "tags": [ + "S3", + "Network Access" + ], + "threatSource": "external threat actor", + "prerequisites": "who has discovered misconfigured S3 hosted website", + "threatAction": "bypass the protections put in place by CloudFront (e.g. geo blocking)", + "impactedGoal": [ + "confidentiality" + ], + "impactedAssets": [ + "this application's data" + ], + "statement": "An external threat actor who has discovered misconfigured S3 hosted website can bypass the protections put in place by CloudFront (e.g. geo blocking), resulting in reduced confidentiality of this application's data" + }, + { + "id": "90619d5b-6450-4108-8013-2eaafc5788b5", + "numericId": 24, + "displayOrder": 24, + "metadata": [ + { + "key": "STRIDE", + "value": [ + "S", + "T", + "I", + "E" + ] + } + ], + "tags": [ + "Secrets Manager", + "AuthN" + ], + "threatSource": "threat actor", + "prerequisites": "who has obtained a long-lived secret (e.g. password)", + "threatAction": "spoof an authenticated user or system", + "threatImpact": "the actor being able to do anything the user or system can do", + "impactedAssets": [ + "this application" + ], + "statement": "A threat actor who has obtained a long-lived secret (e.g. password) can spoof an authenticated user or system, which leads to the actor being able to do anything the user or system can do, negatively impacting this application" + } + ] +}" +`; diff --git a/packages/cdk-graph-plugin-threat-composer/test/plugin-integ.test.ts b/packages/cdk-graph-plugin-threat-composer/test/plugin-integ.test.ts new file mode 100644 index 000000000..1c8814dd6 --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/test/plugin-integ.test.ts @@ -0,0 +1,38 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as fs from "fs"; +import { CdkGraph } from "@aws/cdk-graph"; +import { PDKPipelineIntegApp } from "@aws/cdk-graph/test/__fixtures__/pdk-integ"; +import * as testUtils from "./test-utils"; +import { CdkGraphThreatComposerPlugin } from "../src"; + +jest.setTimeout(90000); + +const makeCdkOutdir = async (name: string) => + testUtils.makeCdkOutDir("plugin-integ", name); + +describe("plugin-integ", () => { + describe("pipeline", () => { + let plugin: CdkGraphThreatComposerPlugin; + + beforeAll(async () => { + const outdir = await makeCdkOutdir("pipeline"); + + const app = new PDKPipelineIntegApp({ outdir }); + plugin = new CdkGraphThreatComposerPlugin(); + const graph = new CdkGraph(app, { + plugins: [plugin], + }); + app.synth(); + await graph.report(); + }); + + it("should generate a threat model", () => { + expect(plugin.threatModelArtifact).toBeDefined(); + expect(fs.existsSync(plugin.threatModelArtifact!.filepath)).toBeTruthy(); + expect( + fs.readFileSync(plugin.threatModelArtifact!.filepath, "utf-8") + ).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/cdk-graph-plugin-threat-composer/test/test-utils.ts b/packages/cdk-graph-plugin-threat-composer/test/test-utils.ts new file mode 100644 index 000000000..ebbf6ec7c --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/test/test-utils.ts @@ -0,0 +1,13 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as path from "path"; +import * as fs from "fs-extra"; + +export async function makeCdkOutDir(...name: string[]): Promise { + const dir = path.join(__dirname, ".tmp", ...name, "cdk.out"); + + await fs.ensureDir(dir); + await fs.emptyDir(dir); + + return dir; +} diff --git a/packages/cdk-graph-plugin-threat-composer/tsconfig.dev.json b/packages/cdk-graph-plugin-threat-composer/tsconfig.dev.json new file mode 100644 index 000000000..8d6bdbf3f --- /dev/null +++ b/packages/cdk-graph-plugin-threat-composer/tsconfig.dev.json @@ -0,0 +1,37 @@ +// ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen". +{ + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "es2019" + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "noImplicitReturns": false, + "noImplicitThis": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "resolveJsonModule": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + "noEmit": true + }, + "include": [ + ".projenrc.js", + "src/**/*.ts", + "test/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/packages/cdk-graph/package.json b/packages/cdk-graph/package.json index 3a96ee1c0..9a30b1619 100644 --- a/packages/cdk-graph/package.json +++ b/packages/cdk-graph/package.json @@ -46,7 +46,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "eslint": "^8", "eslint-config-prettier": "^8.10.0", diff --git a/packages/identity/package.json b/packages/identity/package.json index ff67fbfae..610548e0f 100644 --- a/packages/identity/package.json +++ b/packages/identity/package.json @@ -35,7 +35,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "eslint": "^8", "eslint-config-prettier": "^8.10.0", @@ -59,7 +59,7 @@ "peerDependencies": { "@aws-cdk/aws-cognito-identitypool-alpha": "^2.104.0-alpha.0", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "projen": "^0.76.25" }, diff --git a/packages/infrastructure/samples/infrastructure/java/src/java/groupId/Main.java.mustache b/packages/infrastructure/samples/infrastructure/java/src/java/groupId/Main.java.mustache index 90b23cb0b..8f23e7ccc 100644 --- a/packages/infrastructure/samples/infrastructure/java/src/java/groupId/Main.java.mustache +++ b/packages/infrastructure/samples/infrastructure/java/src/java/groupId/Main.java.mustache @@ -9,6 +9,7 @@ import software.aws.pdk.cdk_graph.IGraphFilterPlan; import software.aws.pdk.cdk_graph_plugin_diagram.CdkGraphDiagramPlugin; import software.aws.pdk.cdk_graph_plugin_diagram.IDiagramConfigBase; import software.aws.pdk.cdk_graph_plugin_diagram.IPluginConfig; +import software.aws.pdk.cdk_graph_plugin_threat_composer.CdkGraphThreatComposerPlugin; import software.aws.pdk.pdk_nag.AwsPrototypingChecks; import software.aws.pdk.pdk_nag.PDKNag; import software.aws.pdk.pdk_nag.PDKNagAppProps; @@ -35,16 +36,19 @@ public class Main { .build()); CdkGraph graph = new CdkGraph(app, ICdkGraphProps.builder() - .plugins(Arrays.asList(new CdkGraphDiagramPlugin(IPluginConfig.builder() - .defaults(IDiagramConfigBase.builder() - .filterPlan(IGraphFilterPlan.builder() - .preset(FilterPreset.COMPACT) - .filters(Arrays.asList(IFilter.builder() - .store(Filters.pruneCustomResources()) - .build())) + .plugins(Arrays.asList( + new CdkGraphDiagramPlugin(IPluginConfig.builder() + .defaults(IDiagramConfigBase.builder() + .filterPlan(IGraphFilterPlan.builder() + .preset(FilterPreset.COMPACT) + .filters(Arrays.asList(IFilter.builder() + .store(Filters.pruneCustomResources()) + .build())) + .build()) .build()) - .build()) - .build()))) + .build()), + new CdkGraphThreatComposerPlugin() + )) .build()); app.synth(); diff --git a/packages/infrastructure/samples/infrastructure/python/src/main.py.mustache b/packages/infrastructure/samples/infrastructure/python/src/main.py.mustache index a8915382c..aa9908688 100644 --- a/packages/infrastructure/samples/infrastructure/python/src/main.py.mustache +++ b/packages/infrastructure/samples/infrastructure/python/src/main.py.mustache @@ -2,6 +2,7 @@ import os from aws_cdk import Environment from aws_pdk.cdk_graph import CdkGraph, FilterPreset, Filters, IFilter, IGraphFilterPlan from aws_pdk.cdk_graph_plugin_diagram import CdkGraphDiagramPlugin, IDiagramConfigBase +from aws_pdk.cdk_graph_plugin_threat_composer import CdkGraphThreatComposerPlugin from aws_pdk.pdk_nag import PDKNag, AwsPrototypingChecks from {{{moduleName}}}.stacks.application_stack import ApplicationStack @@ -14,13 +15,16 @@ dev_env = Environment( app = PDKNag.app(nag_packs=[AwsPrototypingChecks()]) ApplicationStack(app, "{{{stackName}}}", env=dev_env) -graph = CdkGraph(app, plugins=[CdkGraphDiagramPlugin( - defaults=IDiagramConfigBase( - filter_plan=IGraphFilterPlan( - preset=FilterPreset.COMPACT, - filters=[IFilter(store=Filters.prune_custom_resources())] +graph = CdkGraph(app, plugins=[ + CdkGraphDiagramPlugin( + defaults=IDiagramConfigBase( + filter_plan=IGraphFilterPlan( + preset=FilterPreset.COMPACT, + filters=[IFilter(store=Filters.prune_custom_resources())] + ) ) - ) -)]) + ), + CdkGraphThreatComposerPlugin(), +]) app.synth() graph.report() \ No newline at end of file diff --git a/packages/infrastructure/samples/infrastructure/typescript/src/main.ts.mustache b/packages/infrastructure/samples/infrastructure/typescript/src/main.ts.mustache index 5124be4ce..bccc9da05 100644 --- a/packages/infrastructure/samples/infrastructure/typescript/src/main.ts.mustache +++ b/packages/infrastructure/samples/infrastructure/typescript/src/main.ts.mustache @@ -1,5 +1,6 @@ import { CdkGraph, FilterPreset, Filters } from "@aws/pdk/cdk-graph"; import { CdkGraphDiagramPlugin } from "@aws/pdk/cdk-graph-plugin-diagram"; +import { CdkGraphThreatComposerPlugin } from "@aws/pdk/cdk-graph-plugin-threat-composer"; import { AwsPrototypingChecks, PDKNag } from "@aws/pdk/pdk-nag"; import { ApplicationStack } from "./stacks/application-stack"; @@ -27,6 +28,7 @@ const devEnv = { }, }, }), + new CdkGraphThreatComposerPlugin(), ], }); diff --git a/packages/infrastructure/test/projects/java/__snapshots__/infrastructure-java-project.test.ts.snap b/packages/infrastructure/test/projects/java/__snapshots__/infrastructure-java-project.test.ts.snap index 44653b2af..df9e015a5 100644 --- a/packages/infrastructure/test/projects/java/__snapshots__/infrastructure-java-project.test.ts.snap +++ b/packages/infrastructure/test/projects/java/__snapshots__/infrastructure-java-project.test.ts.snap @@ -602,6 +602,7 @@ import software.aws.pdk.cdk_graph.IGraphFilterPlan; import software.aws.pdk.cdk_graph_plugin_diagram.CdkGraphDiagramPlugin; import software.aws.pdk.cdk_graph_plugin_diagram.IDiagramConfigBase; import software.aws.pdk.cdk_graph_plugin_diagram.IPluginConfig; +import software.aws.pdk.cdk_graph_plugin_threat_composer.CdkGraphThreatComposerPlugin; import software.aws.pdk.pdk_nag.AwsPrototypingChecks; import software.aws.pdk.pdk_nag.PDKNag; import software.aws.pdk.pdk_nag.PDKNagAppProps; @@ -628,16 +629,19 @@ public class Main { .build()); CdkGraph graph = new CdkGraph(app, ICdkGraphProps.builder() - .plugins(Arrays.asList(new CdkGraphDiagramPlugin(IPluginConfig.builder() - .defaults(IDiagramConfigBase.builder() - .filterPlan(IGraphFilterPlan.builder() - .preset(FilterPreset.COMPACT) - .filters(Arrays.asList(IFilter.builder() - .store(Filters.pruneCustomResources()) - .build())) + .plugins(Arrays.asList( + new CdkGraphDiagramPlugin(IPluginConfig.builder() + .defaults(IDiagramConfigBase.builder() + .filterPlan(IGraphFilterPlan.builder() + .preset(FilterPreset.COMPACT) + .filters(Arrays.asList(IFilter.builder() + .store(Filters.pruneCustomResources()) + .build())) + .build()) .build()) - .build()) - .build()))) + .build()), + new CdkGraphThreatComposerPlugin() + )) .build()); app.synth(); @@ -1316,6 +1320,7 @@ import software.aws.pdk.cdk_graph.IGraphFilterPlan; import software.aws.pdk.cdk_graph_plugin_diagram.CdkGraphDiagramPlugin; import software.aws.pdk.cdk_graph_plugin_diagram.IDiagramConfigBase; import software.aws.pdk.cdk_graph_plugin_diagram.IPluginConfig; +import software.aws.pdk.cdk_graph_plugin_threat_composer.CdkGraphThreatComposerPlugin; import software.aws.pdk.pdk_nag.AwsPrototypingChecks; import software.aws.pdk.pdk_nag.PDKNag; import software.aws.pdk.pdk_nag.PDKNagAppProps; @@ -1342,16 +1347,19 @@ public class Main { .build()); CdkGraph graph = new CdkGraph(app, ICdkGraphProps.builder() - .plugins(Arrays.asList(new CdkGraphDiagramPlugin(IPluginConfig.builder() - .defaults(IDiagramConfigBase.builder() - .filterPlan(IGraphFilterPlan.builder() - .preset(FilterPreset.COMPACT) - .filters(Arrays.asList(IFilter.builder() - .store(Filters.pruneCustomResources()) - .build())) + .plugins(Arrays.asList( + new CdkGraphDiagramPlugin(IPluginConfig.builder() + .defaults(IDiagramConfigBase.builder() + .filterPlan(IGraphFilterPlan.builder() + .preset(FilterPreset.COMPACT) + .filters(Arrays.asList(IFilter.builder() + .store(Filters.pruneCustomResources()) + .build())) + .build()) .build()) - .build()) - .build()))) + .build()), + new CdkGraphThreatComposerPlugin() + )) .build()); app.synth(); @@ -2107,6 +2115,7 @@ import software.aws.pdk.cdk_graph.IGraphFilterPlan; import software.aws.pdk.cdk_graph_plugin_diagram.CdkGraphDiagramPlugin; import software.aws.pdk.cdk_graph_plugin_diagram.IDiagramConfigBase; import software.aws.pdk.cdk_graph_plugin_diagram.IPluginConfig; +import software.aws.pdk.cdk_graph_plugin_threat_composer.CdkGraphThreatComposerPlugin; import software.aws.pdk.pdk_nag.AwsPrototypingChecks; import software.aws.pdk.pdk_nag.PDKNag; import software.aws.pdk.pdk_nag.PDKNagAppProps; @@ -2133,16 +2142,19 @@ public class Main { .build()); CdkGraph graph = new CdkGraph(app, ICdkGraphProps.builder() - .plugins(Arrays.asList(new CdkGraphDiagramPlugin(IPluginConfig.builder() - .defaults(IDiagramConfigBase.builder() - .filterPlan(IGraphFilterPlan.builder() - .preset(FilterPreset.COMPACT) - .filters(Arrays.asList(IFilter.builder() - .store(Filters.pruneCustomResources()) - .build())) + .plugins(Arrays.asList( + new CdkGraphDiagramPlugin(IPluginConfig.builder() + .defaults(IDiagramConfigBase.builder() + .filterPlan(IGraphFilterPlan.builder() + .preset(FilterPreset.COMPACT) + .filters(Arrays.asList(IFilter.builder() + .store(Filters.pruneCustomResources()) + .build())) + .build()) .build()) - .build()) - .build()))) + .build()), + new CdkGraphThreatComposerPlugin() + )) .build()); app.synth(); @@ -2930,6 +2942,7 @@ import software.aws.pdk.cdk_graph.IGraphFilterPlan; import software.aws.pdk.cdk_graph_plugin_diagram.CdkGraphDiagramPlugin; import software.aws.pdk.cdk_graph_plugin_diagram.IDiagramConfigBase; import software.aws.pdk.cdk_graph_plugin_diagram.IPluginConfig; +import software.aws.pdk.cdk_graph_plugin_threat_composer.CdkGraphThreatComposerPlugin; import software.aws.pdk.pdk_nag.AwsPrototypingChecks; import software.aws.pdk.pdk_nag.PDKNag; import software.aws.pdk.pdk_nag.PDKNagAppProps; @@ -2956,16 +2969,19 @@ public class Main { .build()); CdkGraph graph = new CdkGraph(app, ICdkGraphProps.builder() - .plugins(Arrays.asList(new CdkGraphDiagramPlugin(IPluginConfig.builder() - .defaults(IDiagramConfigBase.builder() - .filterPlan(IGraphFilterPlan.builder() - .preset(FilterPreset.COMPACT) - .filters(Arrays.asList(IFilter.builder() - .store(Filters.pruneCustomResources()) - .build())) + .plugins(Arrays.asList( + new CdkGraphDiagramPlugin(IPluginConfig.builder() + .defaults(IDiagramConfigBase.builder() + .filterPlan(IGraphFilterPlan.builder() + .preset(FilterPreset.COMPACT) + .filters(Arrays.asList(IFilter.builder() + .store(Filters.pruneCustomResources()) + .build())) + .build()) .build()) - .build()) - .build()))) + .build()), + new CdkGraphThreatComposerPlugin() + )) .build()); app.synth(); diff --git a/packages/infrastructure/test/projects/python/__snapshots__/infrastructure-py-project.test.ts.snap b/packages/infrastructure/test/projects/python/__snapshots__/infrastructure-py-project.test.ts.snap index fe61606b4..c7975fb57 100644 --- a/packages/infrastructure/test/projects/python/__snapshots__/infrastructure-py-project.test.ts.snap +++ b/packages/infrastructure/test/projects/python/__snapshots__/infrastructure-py-project.test.ts.snap @@ -439,6 +439,7 @@ class ApplicationStack(Stack): from aws_cdk import Environment from aws_pdk.cdk_graph import CdkGraph, FilterPreset, Filters, IFilter, IGraphFilterPlan from aws_pdk.cdk_graph_plugin_diagram import CdkGraphDiagramPlugin, IDiagramConfigBase +from aws_pdk.cdk_graph_plugin_threat_composer import CdkGraphThreatComposerPlugin from aws_pdk.pdk_nag import PDKNag, AwsPrototypingChecks from infra.stacks.application_stack import ApplicationStack @@ -451,14 +452,17 @@ dev_env = Environment( app = PDKNag.app(nag_packs=[AwsPrototypingChecks()]) ApplicationStack(app, "infra-dev", env=dev_env) -graph = CdkGraph(app, plugins=[CdkGraphDiagramPlugin( - defaults=IDiagramConfigBase( - filter_plan=IGraphFilterPlan( - preset=FilterPreset.COMPACT, - filters=[IFilter(store=Filters.prune_custom_resources())] +graph = CdkGraph(app, plugins=[ + CdkGraphDiagramPlugin( + defaults=IDiagramConfigBase( + filter_plan=IGraphFilterPlan( + preset=FilterPreset.COMPACT, + filters=[IFilter(store=Filters.prune_custom_resources())] + ) ) - ) -)]) + ), + CdkGraphThreatComposerPlugin(), +]) app.synth() graph.report()", "poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". @@ -916,6 +920,7 @@ class ApplicationStack(Stack): from aws_cdk import Environment from aws_pdk.cdk_graph import CdkGraph, FilterPreset, Filters, IFilter, IGraphFilterPlan from aws_pdk.cdk_graph_plugin_diagram import CdkGraphDiagramPlugin, IDiagramConfigBase +from aws_pdk.cdk_graph_plugin_threat_composer import CdkGraphThreatComposerPlugin from aws_pdk.pdk_nag import PDKNag, AwsPrototypingChecks from infra.stacks.application_stack import ApplicationStack @@ -928,14 +933,17 @@ dev_env = Environment( app = PDKNag.app(nag_packs=[AwsPrototypingChecks()]) ApplicationStack(app, "infra-dev", env=dev_env) -graph = CdkGraph(app, plugins=[CdkGraphDiagramPlugin( - defaults=IDiagramConfigBase( - filter_plan=IGraphFilterPlan( - preset=FilterPreset.COMPACT, - filters=[IFilter(store=Filters.prune_custom_resources())] +graph = CdkGraph(app, plugins=[ + CdkGraphDiagramPlugin( + defaults=IDiagramConfigBase( + filter_plan=IGraphFilterPlan( + preset=FilterPreset.COMPACT, + filters=[IFilter(store=Filters.prune_custom_resources())] + ) ) - ) -)]) + ), + CdkGraphThreatComposerPlugin(), +]) app.synth() graph.report()", "infra/poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". @@ -1565,6 +1573,7 @@ class ApplicationStack(Stack): from aws_cdk import Environment from aws_pdk.cdk_graph import CdkGraph, FilterPreset, Filters, IFilter, IGraphFilterPlan from aws_pdk.cdk_graph_plugin_diagram import CdkGraphDiagramPlugin, IDiagramConfigBase +from aws_pdk.cdk_graph_plugin_threat_composer import CdkGraphThreatComposerPlugin from aws_pdk.pdk_nag import PDKNag, AwsPrototypingChecks from infra.stacks.application_stack import ApplicationStack @@ -1577,14 +1586,17 @@ dev_env = Environment( app = PDKNag.app(nag_packs=[AwsPrototypingChecks()]) ApplicationStack(app, "infra-dev", env=dev_env) -graph = CdkGraph(app, plugins=[CdkGraphDiagramPlugin( - defaults=IDiagramConfigBase( - filter_plan=IGraphFilterPlan( - preset=FilterPreset.COMPACT, - filters=[IFilter(store=Filters.prune_custom_resources())] +graph = CdkGraph(app, plugins=[ + CdkGraphDiagramPlugin( + defaults=IDiagramConfigBase( + filter_plan=IGraphFilterPlan( + preset=FilterPreset.COMPACT, + filters=[IFilter(store=Filters.prune_custom_resources())] + ) ) - ) -)]) + ), + CdkGraphThreatComposerPlugin(), +]) app.synth() graph.report()", "infra/poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". @@ -2156,6 +2168,7 @@ class ApplicationStack(Stack): from aws_cdk import Environment from aws_pdk.cdk_graph import CdkGraph, FilterPreset, Filters, IFilter, IGraphFilterPlan from aws_pdk.cdk_graph_plugin_diagram import CdkGraphDiagramPlugin, IDiagramConfigBase +from aws_pdk.cdk_graph_plugin_threat_composer import CdkGraphThreatComposerPlugin from aws_pdk.pdk_nag import PDKNag, AwsPrototypingChecks from infra.stacks.application_stack import ApplicationStack @@ -2168,14 +2181,17 @@ dev_env = Environment( app = PDKNag.app(nag_packs=[AwsPrototypingChecks()]) ApplicationStack(app, "infra-dev", env=dev_env) -graph = CdkGraph(app, plugins=[CdkGraphDiagramPlugin( - defaults=IDiagramConfigBase( - filter_plan=IGraphFilterPlan( - preset=FilterPreset.COMPACT, - filters=[IFilter(store=Filters.prune_custom_resources())] +graph = CdkGraph(app, plugins=[ + CdkGraphDiagramPlugin( + defaults=IDiagramConfigBase( + filter_plan=IGraphFilterPlan( + preset=FilterPreset.COMPACT, + filters=[IFilter(store=Filters.prune_custom_resources())] + ) ) - ) -)]) + ), + CdkGraphThreatComposerPlugin(), +]) app.synth() graph.report()", "infra/poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". diff --git a/packages/infrastructure/test/projects/typescript/__snapshots__/infrastructure-ts-project.test.ts.snap b/packages/infrastructure/test/projects/typescript/__snapshots__/infrastructure-ts-project.test.ts.snap index 82b6a133d..438aff803 100644 --- a/packages/infrastructure/test/projects/typescript/__snapshots__/infrastructure-ts-project.test.ts.snap +++ b/packages/infrastructure/test/projects/typescript/__snapshots__/infrastructure-ts-project.test.ts.snap @@ -1180,6 +1180,7 @@ Refer to [Developer Guide](https://aws.github.io/aws-pdk/developer_guides/infras }, "src/main.ts": "import { CdkGraph, FilterPreset, Filters } from "@aws/pdk/cdk-graph"; import { CdkGraphDiagramPlugin } from "@aws/pdk/cdk-graph-plugin-diagram"; +import { CdkGraphThreatComposerPlugin } from "@aws/pdk/cdk-graph-plugin-threat-composer"; import { AwsPrototypingChecks, PDKNag } from "@aws/pdk/pdk-nag"; import { ApplicationStack } from "./stacks/application-stack"; @@ -1207,6 +1208,7 @@ const devEnv = { }, }, }), + new CdkGraphThreatComposerPlugin(), ], }); @@ -2420,6 +2422,7 @@ export class ApiConstruct extends Construct { ", "infra/src/main.ts": "import { CdkGraph, FilterPreset, Filters } from "@aws/pdk/cdk-graph"; import { CdkGraphDiagramPlugin } from "@aws/pdk/cdk-graph-plugin-diagram"; +import { CdkGraphThreatComposerPlugin } from "@aws/pdk/cdk-graph-plugin-threat-composer"; import { AwsPrototypingChecks, PDKNag } from "@aws/pdk/pdk-nag"; import { ApplicationStack } from "./stacks/application-stack"; @@ -2447,6 +2450,7 @@ const devEnv = { }, }, }), + new CdkGraphThreatComposerPlugin(), ], }); @@ -3726,6 +3730,7 @@ export class WebsiteConstruct extends Construct { ", "infra/src/main.ts": "import { CdkGraph, FilterPreset, Filters } from "@aws/pdk/cdk-graph"; import { CdkGraphDiagramPlugin } from "@aws/pdk/cdk-graph-plugin-diagram"; +import { CdkGraphThreatComposerPlugin } from "@aws/pdk/cdk-graph-plugin-threat-composer"; import { AwsPrototypingChecks, PDKNag } from "@aws/pdk/pdk-nag"; import { ApplicationStack } from "./stacks/application-stack"; @@ -3753,6 +3758,7 @@ const devEnv = { }, }, }), + new CdkGraphThreatComposerPlugin(), ], }); @@ -4950,6 +4956,7 @@ export class WebsiteConstruct extends Construct { ", "infra/src/main.ts": "import { CdkGraph, FilterPreset, Filters } from "@aws/pdk/cdk-graph"; import { CdkGraphDiagramPlugin } from "@aws/pdk/cdk-graph-plugin-diagram"; +import { CdkGraphThreatComposerPlugin } from "@aws/pdk/cdk-graph-plugin-threat-composer"; import { AwsPrototypingChecks, PDKNag } from "@aws/pdk/pdk-nag"; import { ApplicationStack } from "./stacks/application-stack"; @@ -4977,6 +4984,7 @@ const devEnv = { }, }, }), + new CdkGraphThreatComposerPlugin(), ], }); diff --git a/packages/pdk-nag/package.json b/packages/pdk-nag/package.json index 67471455d..4adf08b19 100644 --- a/packages/pdk-nag/package.json +++ b/packages/pdk-nag/package.json @@ -37,7 +37,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "eslint": "^8", "eslint-config-prettier": "^8.10.0", @@ -62,7 +62,7 @@ }, "peerDependencies": { "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0" }, "main": "lib/index.js", diff --git a/packages/pdk-nag/src/index.ts b/packages/pdk-nag/src/index.ts index 4c3beb4c1..b21f8ac59 100644 --- a/packages/pdk-nag/src/index.ts +++ b/packages/pdk-nag/src/index.ts @@ -2,3 +2,4 @@ SPDX-License-Identifier: Apache-2.0 */ export * from "./pdk-nag"; export * from "./packs/aws-prototyping"; +export * from "./loggers/types"; diff --git a/packages/pdk-nag/src/loggers/memory-logger.ts b/packages/pdk-nag/src/loggers/memory-logger.ts new file mode 100644 index 000000000..19f135a7c --- /dev/null +++ b/packages/pdk-nag/src/loggers/memory-logger.ts @@ -0,0 +1,57 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import { + INagLogger, + NagLoggerComplianceData, + NagLoggerErrorData, + NagLoggerNonComplianceData, + NagLoggerNotApplicableData, + NagLoggerSuppressedData, + NagLoggerSuppressedErrorData, +} from "cdk-nag"; +import { ExtendedNagResult, NagResultCompliance } from "./types"; + +/** + * Records nag results in memory + */ +export class MemoryLogger implements INagLogger { + public readonly results: ExtendedNagResult[] = []; + + onCompliance(data: NagLoggerComplianceData): void { + this.results.push({ + ...data, + compliance: NagResultCompliance.COMPLIANT, + }); + } + onNonCompliance(data: NagLoggerNonComplianceData): void { + this.results.push({ + ...data, + compliance: NagResultCompliance.NON_COMPLIANT, + }); + } + onSuppressed(data: NagLoggerSuppressedData): void { + this.results.push({ + ...data, + compliance: NagResultCompliance.NON_COMPLIANT_SUPPRESSED, + }); + } + onError(data: NagLoggerErrorData): void { + this.results.push({ + ...data, + compliance: NagResultCompliance.ERROR, + }); + } + onSuppressedError(data: NagLoggerSuppressedErrorData): void { + this.results.push({ + ...data, + compliance: NagResultCompliance.ERROR_SUPPRESSED, + suppressionReason: data.errorSuppressionReason, + }); + } + onNotApplicable(data: NagLoggerNotApplicableData): void { + this.results.push({ + ...data, + compliance: NagResultCompliance.NOT_APPLICABLE, + }); + } +} diff --git a/packages/pdk-nag/src/loggers/types.ts b/packages/pdk-nag/src/loggers/types.ts new file mode 100644 index 000000000..3802e1254 --- /dev/null +++ b/packages/pdk-nag/src/loggers/types.ts @@ -0,0 +1,84 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import { CfnResource } from "aws-cdk-lib"; +import { NagMessageLevel } from "cdk-nag"; + +/** + * Possible statuses for nag rules + */ +export enum NagResultCompliance { + /** + * Resource complies with the rule + */ + COMPLIANT = "COMPLIANT", + /** + * Resource does not comply with the rule + */ + NON_COMPLIANT = "NON_COMPLIANT", + /** + * Resource does not comply with the rule, but the rule was suppressed + */ + NON_COMPLIANT_SUPPRESSED = "NON_COMPLIANT_SUPPRESSED", + /** + * An error occurred applying the rule + */ + ERROR = "ERROR", + /** + * An error occurred applying the rule, but the rule was suppressed + */ + ERROR_SUPPRESSED = "ERROR_SUPPRESSED", + /** + * The rule is not applicable to the resource + */ + NOT_APPLICABLE = "NOT_APPLICABLE", +} + +/** + * Represents the result of applying a CDK Nag rule to a resource + */ +export interface ExtendedNagResult { + /** + * The name of the nag pack this rule is from + */ + readonly nagPackName: string; + /** + * The resource the rule was applied to + */ + readonly resource: CfnResource; + /** + * The ID of the rule in this nag pack + */ + readonly ruleId: string; + /** + * The original name of the rule (regardless of nag pack) + */ + readonly ruleOriginalName: string; + /** + * Why the rule was triggered + */ + readonly ruleInfo: string; + /** + * Why the rule exists + */ + readonly ruleExplanation: string; + /** + * The severity level of the rule + */ + readonly ruleLevel: NagMessageLevel; + /** + * Compliance status of the rule against the resource + */ + readonly compliance: NagResultCompliance; + /** + * The finding that was checked, only set for non-compliant results + */ + readonly findingId?: string; + /** + * The reason the rule was suppressed, if any + */ + readonly suppressionReason?: string; + /** + * The error that was thrown, only set for error results + */ + readonly errorMessage?: string; +} diff --git a/packages/pdk-nag/src/pdk-nag.ts b/packages/pdk-nag/src/pdk-nag.ts index ca090c391..8e67001ee 100644 --- a/packages/pdk-nag/src/pdk-nag.ts +++ b/packages/pdk-nag/src/pdk-nag.ts @@ -17,6 +17,8 @@ import { NagSuppressions, } from "cdk-nag"; import { IConstruct } from "constructs"; +import { MemoryLogger } from "./loggers/memory-logger"; +import { ExtendedNagResult } from "./loggers/types"; const CDK_NAG_MESSAGE_TYPES = { ERROR: "aws:cdk:error", @@ -91,6 +93,7 @@ export interface PDKNagAppProps extends AppProps { */ export class PDKNagApp extends App { private readonly _nagResults: NagResult[] = []; + private readonly _extendedNagResults: ExtendedNagResult[] = []; private readonly failOnError: boolean; private readonly failOnWarning: boolean; public readonly nagPacks: NagPack[]; @@ -100,6 +103,8 @@ export class PDKNagApp extends App { this.failOnError = props?.failOnError ?? false; this.failOnWarning = props?.failOnWarning ?? false; this.nagPacks = props?.nagPacks ?? DEFAULT_NAG_PACKS; + + Aspects.of(this).add(new PDKNagAspect(this)); } synth(options?: StageSynthesisOptions): CloudAssembly { @@ -134,6 +139,19 @@ export class PDKNagApp extends App { public nagResults(): NagResult[] { return this._nagResults; } + + addExtendedNagResults(...results: ExtendedNagResult[]) { + this._extendedNagResults.push(...results); + } + + /** + * Returns a list of ExtendedNagResult. + * + * Note: app.synth() must be called before this to retrieve results. + */ + public extendedNagResults(): ExtendedNagResult[] { + return this._extendedNagResults; + } } class PDKNagAspect implements IAspect { @@ -144,7 +162,16 @@ class PDKNagAspect implements IAspect { } visit(node: IConstruct): void { - this.app.nagPacks.forEach((nagPack) => nagPack.visit(node)); + const memoryLogger = new MemoryLogger(); + + this.app.nagPacks.forEach((nagPack) => { + // @ts-ignore loggers is private, but since we haven't called "visit" yet it's safe to add another + nagPack.loggers.push(memoryLogger); + nagPack.visit(node); + // @ts-ignore loggers is private, but remove the memory logger to clean up + nagPack.loggers.pop(); + }); + this.app.addExtendedNagResults(...memoryLogger.results); const results = node.node.metadata.filter((m) => CDK_NAG_MESSAGE_TYPES_SET.has(m.type) @@ -170,10 +197,7 @@ export class PDKNag { * @param props props to initialize the app with. */ public static app(props?: PDKNagAppProps): PDKNagApp { - const app = new PDKNagApp(props); - Aspects.of(app).add(new PDKNagAspect(app)); - - return app; + return new PDKNagApp(props); } /** diff --git a/packages/pdk-nag/test/pdk-nag.test.ts b/packages/pdk-nag/test/pdk-nag.test.ts index 3e9275f21..fb85f6709 100644 --- a/packages/pdk-nag/test/pdk-nag.test.ts +++ b/packages/pdk-nag/test/pdk-nag.test.ts @@ -43,6 +43,11 @@ describe("PDK Nag Aspect Tests", () => { ); expect(messages.length).toEqual(0); + + expect(app.extendedNagResults().length).toBeGreaterThan(0); + expect( + app.extendedNagResults().filter((m) => !nagPacksSet.has(m.nagPackName)) + ).toHaveLength(0); }); }); }); diff --git a/packages/pdk/.gitignore b/packages/pdk/.gitignore index 73a7ce8cb..919943174 100644 --- a/packages/pdk/.gitignore +++ b/packages/pdk/.gitignore @@ -56,6 +56,7 @@ cloudscape-react-ts-website aws-arch cdk-graph cdk-graph-plugin-diagram +cdk-graph-plugin-threat-composer pipeline infrastructure /dist/changelog.md diff --git a/packages/pdk/.npmignore b/packages/pdk/.npmignore index 32638c3fc..88f8f266c 100644 --- a/packages/pdk/.npmignore +++ b/packages/pdk/.npmignore @@ -41,6 +41,7 @@ project.json !/aws-arch !/cdk-graph !/cdk-graph-plugin-diagram +!/cdk-graph-plugin-threat-composer !/pipeline !/infrastructure !/pdk @@ -53,6 +54,7 @@ project.json /aws-arch/**/*.ts /cdk-graph/**/*.ts /cdk-graph-plugin-diagram/**/*.ts +/cdk-graph-plugin-threat-composer/**/*.ts /pipeline/**/*.ts /infrastructure/**/*.ts /pdk/**/*.ts @@ -65,6 +67,7 @@ project.json !/aws-arch/**/*.d.ts !/cdk-graph/**/*.d.ts !/cdk-graph-plugin-diagram/**/*.d.ts +!/cdk-graph-plugin-threat-composer/**/*.d.ts !/pipeline/**/*.d.ts !/infrastructure/**/*.d.ts !/pdk/**/*.d.ts diff --git a/packages/pdk/.projen/tasks.json b/packages/pdk/.projen/tasks.json index 9da16e404..21707b5df 100644 --- a/packages/pdk/.projen/tasks.json +++ b/packages/pdk/.projen/tasks.json @@ -158,7 +158,7 @@ "exec": "rm -f tsconfig.json" }, { - "exec": "rm -rf index.* samples scripts assets pdk-nag monorepo static-website identity type-safe-api cloudscape-react-ts-website aws-arch cdk-graph cdk-graph-plugin-diagram pipeline infrastructure" + "exec": "rm -rf index.* samples scripts assets pdk-nag monorepo static-website identity type-safe-api cloudscape-react-ts-website aws-arch cdk-graph cdk-graph-plugin-diagram cdk-graph-plugin-threat-composer pipeline infrastructure" }, { "exec": "if [ -d \"../pdk-nag/src/\" ]; then mkdir -p ././pdk-nag/. && rsync -a ../pdk-nag/src/ ././pdk-nag/. --prune-empty-dirs; fi;" @@ -295,6 +295,21 @@ { "exec": "mkdir -p ./cdk-graph-plugin-diagram && rsync --exclude=**/*.ts -a ../cdk-graph-plugin-diagram/src/ ./cdk-graph-plugin-diagram --prune-empty-dirs" }, + { + "exec": "if [ -d \"../cdk-graph-plugin-threat-composer/src/\" ]; then mkdir -p ././cdk-graph-plugin-threat-composer/. && rsync -a ../cdk-graph-plugin-threat-composer/src/ ././cdk-graph-plugin-threat-composer/. --prune-empty-dirs; fi;" + }, + { + "exec": "if [ -d \"../cdk-graph-plugin-threat-composer/samples/\" ]; then mkdir -p ././cdk-graph-plugin-threat-composer/../samples && rsync -a ../cdk-graph-plugin-threat-composer/samples/ ././cdk-graph-plugin-threat-composer/../samples --prune-empty-dirs; fi;" + }, + { + "exec": "if [ -d \"../cdk-graph-plugin-threat-composer/scripts/\" ]; then mkdir -p ././cdk-graph-plugin-threat-composer/../scripts && rsync -a ../cdk-graph-plugin-threat-composer/scripts/ ././cdk-graph-plugin-threat-composer/../scripts --prune-empty-dirs; fi;" + }, + { + "exec": "if [ -d \"../cdk-graph-plugin-threat-composer/assets/\" ]; then mkdir -p ././cdk-graph-plugin-threat-composer/../assets && rsync -a ../cdk-graph-plugin-threat-composer/assets/ ././cdk-graph-plugin-threat-composer/../assets --prune-empty-dirs; fi;" + }, + { + "exec": "mkdir -p ./cdk-graph-plugin-threat-composer && rsync --exclude=**/*.ts -a ../cdk-graph-plugin-threat-composer/src/ ./cdk-graph-plugin-threat-composer --prune-empty-dirs" + }, { "exec": "if [ -d \"../pipeline/src/\" ]; then mkdir -p ././pipeline/. && rsync -a ../pipeline/src/ ././pipeline/. --prune-empty-dirs; fi;" }, @@ -326,7 +341,7 @@ "exec": "mkdir -p ./infrastructure && rsync --exclude=**/*.ts -a ../infrastructure/src/ ./infrastructure --prune-empty-dirs" }, { - "exec": "echo 'export * as pdk_nag from \"./pdk-nag\";\nexport * as monorepo from \"./monorepo\";\nexport * as static_website from \"./static-website\";\nexport * as identity from \"./identity\";\nexport * as type_safe_api from \"./type-safe-api\";\nexport * as cloudscape_react_ts_website from \"./cloudscape-react-ts-website\";\nexport * as aws_arch from \"./aws-arch\";\nexport * as cdk_graph from \"./cdk-graph\";\nexport * as cdk_graph_plugin_diagram from \"./cdk-graph-plugin-diagram\";\nexport * as pipeline from \"./pipeline\";\nexport * as infrastructure from \"./infrastructure\";' > ./index.ts" + "exec": "echo 'export * as pdk_nag from \"./pdk-nag\";\nexport * as monorepo from \"./monorepo\";\nexport * as static_website from \"./static-website\";\nexport * as identity from \"./identity\";\nexport * as type_safe_api from \"./type-safe-api\";\nexport * as cloudscape_react_ts_website from \"./cloudscape-react-ts-website\";\nexport * as aws_arch from \"./aws-arch\";\nexport * as cdk_graph from \"./cdk-graph\";\nexport * as cdk_graph_plugin_diagram from \"./cdk-graph-plugin-diagram\";\nexport * as cdk_graph_plugin_threat_composer from \"./cdk-graph-plugin-threat-composer\";\nexport * as pipeline from \"./pipeline\";\nexport * as infrastructure from \"./infrastructure\";' > ./index.ts" } ] }, diff --git a/packages/pdk/README.md b/packages/pdk/README.md index 02f6d084f..6ed298316 100644 --- a/packages/pdk/README.md +++ b/packages/pdk/README.md @@ -14,6 +14,10 @@ Please refer to [Developer Guide](./docs/developer_guides/cdk-graph/index.md). Please refer to [Developer Guide](./docs/developer_guides/cdk-graph-plugin-diagram/index.md). +# cdk-graph-plugin-threat-composer + +Please refer to [Developer Guide](./docs/developer_guides/cdk-graph-plugin-threat-composer/index.md). + # cloudscape-react-ts-website Please refer to [Developer Guide](./docs/developer_guides/cloudscape-react-ts-website/index.md). diff --git a/packages/pdk/package.json b/packages/pdk/package.json index 2b7a9973a..a4c01818f 100644 --- a/packages/pdk/package.json +++ b/packages/pdk/package.json @@ -73,7 +73,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "downlevel-dts": "^0.11.0", "eslint": "^8", @@ -109,7 +109,7 @@ "peerDependencies": { "@aws-cdk/aws-cognito-identitypool-alpha": "^2.104.0-alpha.0", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "projen": "^0.76.25" }, @@ -252,6 +252,9 @@ "@aws/cdk-graph-plugin-diagram": [ "./cdk-graph-plugin-diagram" ], + "@aws/cdk-graph-plugin-threat-composer": [ + "./cdk-graph-plugin-threat-composer" + ], "@aws/pipeline": [ "./pipeline" ], diff --git a/packages/pdk/project.json b/packages/pdk/project.json index 80b5a857d..345fd108e 100644 --- a/packages/pdk/project.json +++ b/packages/pdk/project.json @@ -142,6 +142,7 @@ "@aws/aws-arch", "@aws/cdk-graph", "@aws/cdk-graph-plugin-diagram", + "@aws/cdk-graph-plugin-threat-composer", "@aws/pipeline", "@aws/infrastructure" ], diff --git a/packages/pdk/tsconfig.dev.json b/packages/pdk/tsconfig.dev.json index d451215f9..864d21719 100644 --- a/packages/pdk/tsconfig.dev.json +++ b/packages/pdk/tsconfig.dev.json @@ -52,6 +52,9 @@ "@aws/cdk-graph-plugin-diagram": [ "./cdk-graph-plugin-diagram" ], + "@aws/cdk-graph-plugin-threat-composer": [ + "./cdk-graph-plugin-threat-composer" + ], "@aws/pipeline": [ "./pipeline" ], diff --git a/packages/pipeline/package.json b/packages/pipeline/package.json index 888941de3..981aec530 100644 --- a/packages/pipeline/package.json +++ b/packages/pipeline/package.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "eslint": "^8", "eslint-config-prettier": "^8.10.0", @@ -57,7 +57,7 @@ }, "peerDependencies": { "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "projen": "^0.76.25" }, diff --git a/packages/static-website/package.json b/packages/static-website/package.json index 75af9b2df..339051a6f 100644 --- a/packages/static-website/package.json +++ b/packages/static-website/package.json @@ -35,7 +35,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "eslint": "^8", "eslint-config-prettier": "^8.10.0", @@ -58,7 +58,7 @@ }, "peerDependencies": { "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "projen": "^0.76.25" }, diff --git a/packages/type-safe-api/package.json b/packages/type-safe-api/package.json index 040fcb63f..d3c75ed2a 100644 --- a/packages/type-safe-api/package.json +++ b/packages/type-safe-api/package.json @@ -48,7 +48,7 @@ "@typescript-eslint/eslint-plugin": "^6", "@typescript-eslint/parser": "^6", "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "eslint": "^8", "eslint-config-prettier": "^8.10.0", @@ -73,7 +73,7 @@ }, "peerDependencies": { "aws-cdk-lib": "^2.104.0", - "cdk-nag": "^2.27.184", + "cdk-nag": "^2.28.2", "constructs": "^10.3.0", "projen": "^0.76.25" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 384b120cb..520859e22 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,8 +28,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) fast-xml-parser: specifier: ^4.3.2 version: 4.3.2 @@ -376,8 +376,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -608,6 +608,103 @@ importers: specifier: ^5.2.2 version: 5.2.2 + packages/cdk-graph-plugin-threat-composer: + dependencies: + lodash: + specifier: ^4.17.21 + version: 4.17.21 + devDependencies: + '@aws/aws-arch': + specifier: 0.0.0 + version: link:../aws-arch + '@aws/cdk-graph': + specifier: 0.0.0 + version: link:../cdk-graph + '@aws/pdk-nag': + specifier: 0.0.0 + version: link:../pdk-nag + '@types/jest': + specifier: ^29.5.7 + version: 29.5.7 + '@types/lodash': + specifier: ^4.14.200 + version: 4.14.200 + '@types/node': + specifier: ^18 + version: 18.18.9 + '@typescript-eslint/eslint-plugin': + specifier: ^6 + version: 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.39.0)(typescript@5.2.2) + '@typescript-eslint/parser': + specifier: ^6 + version: 6.5.0(eslint@8.39.0)(typescript@5.2.2) + aws-cdk-lib: + specifier: 2.104.0 + version: 2.104.0(constructs@10.3.0) + cdk-nag: + specifier: 2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) + constructs: + specifier: 10.3.0 + version: 10.3.0 + eslint: + specifier: ^8 + version: 8.39.0 + eslint-config-prettier: + specifier: ^8.10.0 + version: 8.10.0(eslint@8.39.0) + eslint-import-resolver-node: + specifier: ^0.3.9 + version: 0.3.9 + eslint-import-resolver-typescript: + specifier: ^3.6.1 + version: 3.6.1(@typescript-eslint/parser@6.5.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.39.0) + eslint-plugin-header: + specifier: ^3.1.1 + version: 3.1.1(eslint@8.39.0) + eslint-plugin-import: + specifier: ^2.29.0 + version: 2.29.0(@typescript-eslint/parser@6.5.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.39.0) + eslint-plugin-prettier: + specifier: ^4.2.1 + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.39.0)(prettier@2.8.8) + fs-extra: + specifier: ^11.1.1 + version: 11.1.1 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@18.18.9)(ts-node@10.9.1) + jest-junit: + specifier: ^15 + version: 15.0.0 + jsii: + specifier: ^5.2.24 + version: 5.2.24 + jsii-diff: + specifier: ^1.91.0 + version: 1.91.0 + jsii-docgen: + specifier: ^8.0.56 + version: 8.0.56 + jsii-pacmak: + specifier: ^1.91.0 + version: 1.91.0 + jsii-rosetta: + specifier: ^1.91.0 + version: 1.91.0 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + projen: + specifier: 0.76.25 + version: 0.76.25(constructs@10.3.0) + ts-jest: + specifier: ^29.1.1 + version: 29.1.1(@babel/core@7.21.8)(jest@29.7.0)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + packages/cloudscape-react-ts-website: dependencies: '@aws/type-safe-api': @@ -718,8 +815,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -1159,8 +1256,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -1282,8 +1379,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -1370,8 +1467,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -1455,8 +1552,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -1570,8 +1667,8 @@ importers: specifier: ^2.104.0 version: 2.104.0(constructs@10.3.0) cdk-nag: - specifier: ^2.27.184 - version: 2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0) + specifier: ^2.28.2 + version: 2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0) constructs: specifier: ^10.3.0 version: 10.3.0 @@ -2401,15 +2498,15 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.5 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) '@babel/helper-module-transforms': 7.21.5 '@babel/helpers': 7.21.5 - '@babel/parser': 7.21.8 - '@babel/template': 7.20.7 + '@babel/parser': 7.23.0 + '@babel/template': 7.22.15 '@babel/traverse': 7.23.2 - '@babel/types': 7.21.5 + '@babel/types': 7.23.0 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -2419,16 +2516,6 @@ packages: - supports-color dev: true - /@babel/generator@7.21.5: - resolution: {integrity: sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.5 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true - /@babel/generator@7.23.0: resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} engines: {node: '>=6.9.0'} @@ -6164,8 +6251,8 @@ packages: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true - /cdk-nag@2.27.184(aws-cdk-lib@2.104.0)(constructs@10.3.0): - resolution: {integrity: sha512-g991bCN861x1XLFhuaO99Y9BCGx4DDpopWEh/SYJe5BZOYjJpkiQcHl6bYEfvutaqbVk2XjZMnHxd0utKpJ5yA==} + /cdk-nag@2.28.2(aws-cdk-lib@2.104.0)(constructs@10.3.0): + resolution: {integrity: sha512-ghrTVypp0voJ05MFHnzk0exJBELGYm68Sx2mnEUVJC46NhD2e3yoWeN9Dte/2HFuMq9PjLagpku8H74FW0vN6g==} peerDependencies: aws-cdk-lib: ^2.78.0 constructs: ^10.0.5 @@ -7136,7 +7223,7 @@ packages: dependencies: semver: 7.5.4 shelljs: 0.8.5 - typescript: 5.4.0-dev.20231107 + typescript: 5.4.0-dev.20240107 dev: true /duplexer2@0.0.2: @@ -8068,7 +8155,6 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} @@ -8635,7 +8721,6 @@ packages: engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 - dev: true /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} @@ -8990,7 +9075,6 @@ packages: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: hasown: 2.0.0 - dev: true /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -9239,7 +9323,7 @@ packages: engines: {node: '>=8'} dependencies: '@babel/core': 7.21.8 - '@babel/parser': 7.21.8 + '@babel/parser': 7.23.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.1 @@ -9422,7 +9506,7 @@ packages: chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 - pretty-format: 29.6.3 + pretty-format: 29.7.0 dev: true /jest-diff@29.7.0: @@ -9534,7 +9618,7 @@ packages: chalk: 4.1.2 jest-diff: 29.6.4 jest-get-type: 29.6.3 - pretty-format: 29.6.3 + pretty-format: 29.7.0 dev: true /jest-matcher-utils@29.7.0: @@ -9557,7 +9641,7 @@ packages: chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.5 - pretty-format: 29.6.3 + pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 dev: true @@ -9692,10 +9776,10 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.21.8 - '@babel/generator': 7.21.5 + '@babel/generator': 7.23.0 '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.8) '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.21.8) - '@babel/types': 7.21.5 + '@babel/types': 7.23.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 @@ -11109,7 +11193,7 @@ packages: engines: {node: '>=10'} dependencies: hosted-git-info: 4.1.0 - is-core-module: 2.13.0 + is-core-module: 2.13.1 semver: 7.5.4 validate-npm-package-license: 3.0.4 dev: true @@ -11119,7 +11203,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} dependencies: hosted-git-info: 5.2.1 - is-core-module: 2.13.0 + is-core-module: 2.13.1 semver: 7.5.4 validate-npm-package-license: 3.0.4 dev: true @@ -11129,7 +11213,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: hosted-git-info: 6.1.1 - is-core-module: 2.13.0 + is-core-module: 2.13.1 semver: 7.5.4 validate-npm-package-license: 3.0.4 @@ -14008,8 +14092,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - /typescript@5.4.0-dev.20231107: - resolution: {integrity: sha512-4bQlfsyFjzZMo1bSLEkFJEcvuQ64pgE0S/BpdWu16lYsQOfJZtntZIyWdED3h+e96IMtVgrC6sxzfPZhj4J/dw==} + /typescript@5.4.0-dev.20240107: + resolution: {integrity: sha512-6EfwZFaO82JLhOUsgQ3+c4lHuYS4WAQ6xBC767qWwJGf7BKYYeSFUkSptSkNhWOdeCEhdooudx22mkU8LphAPg==} engines: {node: '>=14.17'} hasBin: true dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 496beeb40..4da0657b3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,7 @@ packages: - packages/aws-arch - packages/cdk-graph - packages/cdk-graph-plugin-diagram + - packages/cdk-graph-plugin-threat-composer - packages/cloudscape-react-ts-website - docs - packages/identity diff --git a/projenrc/projects/cdk-graph-plugin-threat-composer-project.ts b/projenrc/projects/cdk-graph-plugin-threat-composer-project.ts new file mode 100644 index 000000000..0506d9038 --- /dev/null +++ b/projenrc/projects/cdk-graph-plugin-threat-composer-project.ts @@ -0,0 +1,30 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import { Project } from "projen"; +import { Stability } from "projen/lib/cdk"; +import { CdkGraphPluginProject } from "../abstract/cdk-graph-plugin-project"; +import { PDK_NAMESPACE } from "../abstract/pdk-project"; + +/** + * Project for cdk-graph-plugin-threat-composer package + */ +export class CdkGraphPluginThreatComposerProject extends CdkGraphPluginProject { + constructor(parent: Project) { + super({ + parent, + pluginName: "threat-composer", + devDeps: [ + `${PDK_NAMESPACE}pdk-nag@^0.x`, + "cdk-nag", + "@types/lodash", + "fs-extra", + ], + bundledDeps: ["lodash"], + peerDeps: [`${PDK_NAMESPACE}pdk-nag@^0.x`, "cdk-nag"], + stability: Stability.EXPERIMENTAL, + }); + + this.jest!.addIgnorePattern("/\\.tmp/"); + this.jest!.addWatchIgnorePattern("/\\.tmp/"); + } +}