From 650846aed4378bee6a843769cfc8d94b7433c7ad Mon Sep 17 00:00:00 2001 From: clueleaf <10379303+clueleaf@users.noreply.github.com> Date: Wed, 13 Nov 2024 03:44:15 +0900 Subject: [PATCH 1/2] feat: remove AthenaWorkgroupEncryptedQueryResults and CodeBuildProjectPrivilegedModeDisabled (#1838) Fixes #1803 Fixes #1804 --- RULES.md | 8 +- src/packs/aws-solutions.ts | 20 ----- .../AthenaWorkgroupEncryptedQueryResults.ts | 46 ----------- src/rules/athena/index.ts | 5 -- .../CodeBuildProjectPrivilegedModeDisabled.ts | 32 -------- src/rules/codebuild/index.ts | 1 - src/rules/index.ts | 1 - test/Packs.test.ts | 2 - test/rules/Athena.test.ts | 78 ------------------- test/rules/CodeBuild.test.ts | 35 --------- 10 files changed, 3 insertions(+), 225 deletions(-) delete mode 100644 src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts delete mode 100644 src/rules/athena/index.ts delete mode 100644 src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts delete mode 100644 test/rules/Athena.test.ts diff --git a/RULES.md b/RULES.md index 5915505a8e..4408266f81 100644 --- a/RULES.md +++ b/RULES.md @@ -16,7 +16,6 @@ The [AWS Solutions Library](https://aws.amazon.com/solutions/) offers a collecti | Rule ID | Cause | Explanation | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AwsSolutions-APIG3 | The REST API stage is not associated with AWS WAFv2 web ACL. | AWS WAFv2 is a web application firewall that helps protect web applications and APIs from attacks by allowing configured rules to allow, block, or monitor (count) web requests based on customizable rules and conditions that are defined. | -| AwsSolutions-CB3 | The CodeBuild project has privileged mode enabled. | Privileged grants elevated rights to the system, which introduces additional risk. Privileged mode should only be set to true only if the build project is used to build Docker images. Otherwise, a build that attempts to interact with the Docker daemon fails. | | AwsSolutions-CB5 | The Codebuild project does not use images provided by the CodeBuild service or have a cdk-nag suppression rule explaining the need for a custom image. | Explaining differences/edits to Docker images helps operators better understand system dependencies. | | AwsSolutions-CFR1 | The CloudFront distribution may require Geo restrictions. | Geo restriction may need to be enabled for the distribution in order to allow or deny a country in order to allow or restrict users in specific locations from accessing content. | | AwsSolutions-CFR2 | The CloudFront distribution may require integration with AWS WAF. | The Web Application Firewall can help protect against application-layer attacks that can compromise the security of the system or place unnecessary load on them. | @@ -51,7 +50,6 @@ The [AWS Solutions Library](https://aws.amazon.com/solutions/) offers a collecti | AwsSolutions-AS2 | The Auto Scaling Group does not have properly configured health checks. | The health check feature enables the service to detect whether its registered EC2 instances are healthy or not. | | AwsSolutions-AS3 | The Auto Scaling Group does not have notifications configured for all scaling events. | Notifications on EC2 instance launch, launch error, termination, and termination errors allow operators to gain better insights into systems attributes such as activity and health. | | AwsSolutions-ASC3 | The GraphQL API does not have request level logging enabled. | It is important to use CloudWatch Logs to log metrics such as who has accessed the GraphQL API, how the caller accessed the API, and invalid requests. | -| AwsSolutions-ATH1 | The Athena workgroup does not encrypt query results. | Encrypting query results stored in S3 helps secure data to meet compliance requirements for data-at-rest encryption. | | AwsSolutions-CB4 | The CodeBuild project does not use an AWS KMS key for encryption. | Using an AWS KMS key helps follow the standard security advice of granting least privilege to objects generated by the project. | | AwsSolutions-C91 | The Cloud9 instance does not use a no-ingress EC2 instance with AWS Systems Manager. | SSM adds an additional layer of protection as it allows operators to control access through IAM permissions and does not require opening inbound ports. | | AwsSolutions-CFR3 | The CloudFront distribution does not have access logging enabled. | Enabling access logs helps operators track all viewer requests for the content delivered through the Content Delivery Network. | @@ -695,9 +693,9 @@ Unimplemented rules from the AWS PCI DSS 3.2.1 Conformance Pack. A collection of community rules that are not currently included in any of the pre-built NagPacks, but are still available for inclusion in [custom NagPacks](https://github.com/cdklabs/cdk-nag/blob/main/docs/NagPack.md). -| Rule ID | Cause | Explanation | -| ------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| LambdaFunctionUrlAuth | The Lambda Function URL allows for public, unauthenticated access. | AWS Lambda Function URLs allow you to invoke your function via a HTTPS end-point, setting the authentication to NONE allows anyone on the internet to invoke your function. | +| Rule ID | Cause | Explanation | +| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| LambdaFunctionUrlAuth | The Lambda Function URL allows for public, unauthenticated access. | AWS Lambda Function URLs allow you to invoke your function via a HTTPS end-point, setting the authentication to NONE allows anyone on the internet to invoke your function. | | LambdaEventSourceSQSVisibilityTimeout | The SQS queue visibility timeout of Lambda Event Source Mapping is less than 6 times timeout of Lambda function. | Setting the visibility timeout to [at least 6 times the Lambda function timeout](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-lambda-function-trigger.html) helps prevent configurations resulting in duplicate processing of queue items when the Lambda function execution is retried. | ## Footnotes diff --git a/src/packs/aws-solutions.ts b/src/packs/aws-solutions.ts index a798c53e20..5ec4e3c5e7 100644 --- a/src/packs/aws-solutions.ts +++ b/src/packs/aws-solutions.ts @@ -14,7 +14,6 @@ import { APIGWRequestValidation, } from '../rules/apigw'; import { AppSyncGraphQLRequestLogging } from '../rules/appsync'; -import { AthenaWorkgroupEncryptedQueryResults } from '../rules/athena'; import { AutoScalingGroupCooldownPeriod, AutoScalingGroupHealthCheck, @@ -33,7 +32,6 @@ import { import { CodeBuildProjectKMSEncryptedArtifacts, CodeBuildProjectManagedImages, - CodeBuildProjectPrivilegedModeDisabled, } from '../rules/codebuild'; import { CognitoUserPoolAdvancedSecurityModeEnforced, @@ -1007,15 +1005,6 @@ export class AwsSolutionsChecks extends NagPack { * @param ignores list of ignores for the resource */ private checkAnalytics(node: CfnResource): void { - this.applyRule({ - ruleSuffixOverride: 'ATH1', - info: 'The Athena workgroup does not encrypt query results.', - explanation: - 'Encrypting query results stored in S3 helps secure data to meet compliance requirements for data-at-rest encryption.', - level: NagMessageLevel.ERROR, - rule: AthenaWorkgroupEncryptedQueryResults, - node: node, - }); this.applyRule({ ruleSuffixOverride: 'EMR2', info: 'The EMR cluster does not have S3 logging enabled.', @@ -1464,15 +1453,6 @@ export class AwsSolutionsChecks extends NagPack { * @param ignores list of ignores for the resource */ private checkDeveloperTools(node: CfnResource): void { - this.applyRule({ - ruleSuffixOverride: 'CB3', - info: 'The CodeBuild project has privileged mode enabled.', - explanation: - 'Privileged grants elevated rights to the system, which introduces additional risk. Privileged mode should only be set to true only if the build project is used to build Docker images. Otherwise, a build that attempts to interact with the Docker daemon fails.', - level: NagMessageLevel.WARN, - rule: CodeBuildProjectPrivilegedModeDisabled, - node: node, - }); this.applyRule({ ruleSuffixOverride: 'CB4', info: 'The CodeBuild project does not use an AWS KMS key for encryption.', diff --git a/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts b/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts deleted file mode 100644 index 54ed10e953..0000000000 --- a/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ -import { parse } from 'path'; -import { CfnResource, Stack } from 'aws-cdk-lib'; -import { CfnWorkGroup } from 'aws-cdk-lib/aws-athena'; -import { NagRuleCompliance, NagRules } from '../../nag-rules'; - -/** - * Athena workgroups encrypt query results - * @param node the CfnResource to check - */ -export default Object.defineProperty( - (node: CfnResource): NagRuleCompliance => { - if (node instanceof CfnWorkGroup) { - const workGroupConfiguration = Stack.of(node).resolve( - node.workGroupConfiguration - ); - const enforceWorkGroupConfiguration = NagRules.resolveIfPrimitive( - node, - workGroupConfiguration?.enforceWorkGroupConfiguration - ); - if (!enforceWorkGroupConfiguration) { - return NagRuleCompliance.NON_COMPLIANT; - } - const resultConfiguration = Stack.of(node).resolve( - workGroupConfiguration.resultConfiguration - ); - if (resultConfiguration === undefined) { - return NagRuleCompliance.NON_COMPLIANT; - } - const encryptionConfiguration = Stack.of(node).resolve( - resultConfiguration.encryptionConfiguration - ); - if (encryptionConfiguration === undefined) { - return NagRuleCompliance.NON_COMPLIANT; - } - return NagRuleCompliance.COMPLIANT; - } else { - return NagRuleCompliance.NOT_APPLICABLE; - } - }, - 'name', - { value: parse(__filename).name } -); diff --git a/src/rules/athena/index.ts b/src/rules/athena/index.ts deleted file mode 100644 index 5a129734a9..0000000000 --- a/src/rules/athena/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ -export { default as AthenaWorkgroupEncryptedQueryResults } from './AthenaWorkgroupEncryptedQueryResults'; diff --git a/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts b/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts deleted file mode 100644 index 273c93be63..0000000000 --- a/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ -import { parse } from 'path'; -import { CfnResource, Stack } from 'aws-cdk-lib'; -import { CfnProject } from 'aws-cdk-lib/aws-codebuild'; -import { NagRuleCompliance, NagRules } from '../../nag-rules'; - -/** - * Codebuild projects have privileged mode disabled - * @param node the CfnResource to check - */ -export default Object.defineProperty( - (node: CfnResource): NagRuleCompliance => { - if (node instanceof CfnProject) { - const environment = Stack.of(node).resolve(node.environment); - const privilegedMode = NagRules.resolveIfPrimitive( - node, - environment.privilegedMode - ); - if (privilegedMode != undefined && privilegedMode) { - return NagRuleCompliance.NON_COMPLIANT; - } - return NagRuleCompliance.COMPLIANT; - } else { - return NagRuleCompliance.NOT_APPLICABLE; - } - }, - 'name', - { value: parse(__filename).name } -); diff --git a/src/rules/codebuild/index.ts b/src/rules/codebuild/index.ts index f851d2714e..5bc716cde8 100644 --- a/src/rules/codebuild/index.ts +++ b/src/rules/codebuild/index.ts @@ -5,5 +5,4 @@ SPDX-License-Identifier: Apache-2.0 export { default as CodeBuildProjectEnvVarAwsCred } from './CodeBuildProjectEnvVarAwsCred'; export { default as CodeBuildProjectKMSEncryptedArtifacts } from './CodeBuildProjectKMSEncryptedArtifacts'; export { default as CodeBuildProjectManagedImages } from './CodeBuildProjectManagedImages'; -export { default as CodeBuildProjectPrivilegedModeDisabled } from './CodeBuildProjectPrivilegedModeDisabled'; export { default as CodeBuildProjectSourceRepoUrl } from './CodeBuildProjectSourceRepoUrl'; diff --git a/src/rules/index.ts b/src/rules/index.ts index 2c1e901831..b73bafb08e 100644 --- a/src/rules/index.ts +++ b/src/rules/index.ts @@ -4,7 +4,6 @@ SPDX-License-Identifier: Apache-2.0 */ export * as apigw from './apigw'; export * as appsync from './appsync'; -export * as athena from './athena'; export * as autoscaling from './autoscaling'; export * as cloud9 from './cloud9'; export * as cloudfront from './cloudfront'; diff --git a/test/Packs.test.ts b/test/Packs.test.ts index a09f7a5fbc..42ddc3cbd7 100644 --- a/test/Packs.test.ts +++ b/test/Packs.test.ts @@ -39,7 +39,6 @@ describe('Check NagPack Details', () => { test('Pack contains expected warning and error rules', () => { const expectedWarnings = [ 'AwsSolutions-APIG3', - 'AwsSolutions-CB3', 'AwsSolutions-CB5', 'AwsSolutions-CFR1', 'AwsSolutions-CFR2', @@ -71,7 +70,6 @@ describe('Check NagPack Details', () => { 'AwsSolutions-AS2', 'AwsSolutions-AS3', 'AwsSolutions-ASC3', - 'AwsSolutions-ATH1', 'AwsSolutions-CB4', 'AwsSolutions-C91', 'AwsSolutions-CFR3', diff --git a/test/rules/Athena.test.ts b/test/rules/Athena.test.ts deleted file mode 100644 index 8c2ce8cb8f..0000000000 --- a/test/rules/Athena.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ -import { CfnWorkGroup } from 'aws-cdk-lib/aws-athena'; -import { Aspects, Stack } from 'aws-cdk-lib/core'; -import { TestPack, TestType, validateStack } from './utils'; -import { AthenaWorkgroupEncryptedQueryResults } from '../../src/rules/athena'; - -const testPack = new TestPack([AthenaWorkgroupEncryptedQueryResults]); -let stack: Stack; - -beforeEach(() => { - stack = new Stack(); - Aspects.of(stack).add(testPack); -}); - -describe('Amazon Athena', () => { - describe('AthenaWorkgroupEncryptedQueryResults: Athena workgroups encrypt query results', () => { - const ruleId = 'AthenaWorkgroupEncryptedQueryResults'; - test('Noncompliance 1', () => { - new CfnWorkGroup(stack, 'rWorkgroup', { - name: 'foo', - }); - validateStack(stack, ruleId, TestType.NON_COMPLIANCE); - }); - test('Noncompliance 2', () => { - new CfnWorkGroup(stack, 'rWorkgroup', { - name: 'foo', - workGroupConfiguration: { - enforceWorkGroupConfiguration: false, - resultConfiguration: { - encryptionConfiguration: { - encryptionOption: 'SSE_S3', - }, - }, - }, - }); - validateStack(stack, ruleId, TestType.NON_COMPLIANCE); - }); - test('Noncompliance 3', () => { - new CfnWorkGroup(stack, 'rWorkgroup', { - name: 'foo', - workGroupConfiguration: { - enforceWorkGroupConfiguration: true, - requesterPaysEnabled: true, - }, - }); - validateStack(stack, ruleId, TestType.NON_COMPLIANCE); - }); - test('Noncompliance 4', () => { - new CfnWorkGroup(stack, 'rWorkgroup', { - name: 'foo', - workGroupConfiguration: { - enforceWorkGroupConfiguration: true, - resultConfiguration: { - outputLocation: 'bar', - }, - }, - }); - validateStack(stack, ruleId, TestType.NON_COMPLIANCE); - }); - test('Compliance', () => { - new CfnWorkGroup(stack, 'rWorkgroup', { - name: 'foo', - workGroupConfiguration: { - enforceWorkGroupConfiguration: true, - resultConfiguration: { - encryptionConfiguration: { - encryptionOption: 'SSE_S3', - }, - }, - }, - }); - validateStack(stack, ruleId, TestType.COMPLIANCE); - }); - }); -}); diff --git a/test/rules/CodeBuild.test.ts b/test/rules/CodeBuild.test.ts index c973bf400f..7cf7bf4e65 100644 --- a/test/rules/CodeBuild.test.ts +++ b/test/rules/CodeBuild.test.ts @@ -15,7 +15,6 @@ import { CodeBuildProjectEnvVarAwsCred, CodeBuildProjectKMSEncryptedArtifacts, CodeBuildProjectManagedImages, - CodeBuildProjectPrivilegedModeDisabled, CodeBuildProjectSourceRepoUrl, } from '../../src/rules/codebuild'; @@ -23,7 +22,6 @@ const testPack = new TestPack([ CodeBuildProjectEnvVarAwsCred, CodeBuildProjectKMSEncryptedArtifacts, CodeBuildProjectManagedImages, - CodeBuildProjectPrivilegedModeDisabled, CodeBuildProjectSourceRepoUrl, ]); let stack: Stack; @@ -265,39 +263,6 @@ describe('Amazon CodeBuild', () => { }); }); - describe('CodeBuildProjectPrivilegedModeDisabled: Codebuild projects have privileged mode disabled', () => { - const ruleId = 'CodeBuildProjectPrivilegedModeDisabled'; - test('Noncompliance 1', () => { - new Project(stack, 'rBuildProject', { - buildSpec: BuildSpec.fromObjectToYaml({ - version: 0.2, - phases: { - build: { - commands: ['echo "foo"'], - }, - }, - }), - environment: { - privileged: true, - }, - }); - validateStack(stack, ruleId, TestType.NON_COMPLIANCE); - }); - test('Compliance', () => { - new Project(stack, 'rBuildProject', { - buildSpec: BuildSpec.fromObjectToYaml({ - version: 0.2, - phases: { - build: { - commands: ['echo "foo"'], - }, - }, - }), - }); - validateStack(stack, ruleId, TestType.COMPLIANCE); - }); - }); - describe('CodeBuildProjectSourceRepoUrl: Codebuild projects with a GitHub or BitBucket source repository utilize OAUTH', () => { const ruleId = 'CodeBuildProjectSourceRepoUrl'; test('Noncompliance 1', () => { From 09991705bcae10494d639a188a6e0f6b43191362 Mon Sep 17 00:00:00 2001 From: cdklabs-automation <90142015+cdklabs-automation@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:11:26 -0800 Subject: [PATCH 2/2] chore(deps): upgrade dependencies (#1841) Upgrades project dependencies. See details in [workflow run]. [Workflow Run]: https://github.com/cdklabs/cdk-nag/actions/runs/11807903785 ------ *Automatically created by projen via the "upgrade-main" workflow* --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index f6ecfebb56..18f8127f11 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1974,9 +1974,9 @@ downlevel-dts@^0.11.0: typescript next electron-to-chromium@^1.5.41: - version "1.5.56" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz#3213f369efc3a41091c3b2c05bc0f406108ac1df" - integrity sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw== + version "1.5.57" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.57.tgz#cb43af8784166bca24565b3418bf5f775a6b1c86" + integrity sha512-xS65H/tqgOwUBa5UmOuNSLuslDo7zho0y/lgQw35pnrqiZh7UOWHCeL/Bt6noJATbA6tpQJGCifsFsIRZj1Fqg== emittery@^0.8.1: version "0.8.1" @@ -4926,9 +4926,9 @@ stream-chain@^2.2.5: integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== stream-json@^1.8.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.9.0.tgz#caae36fd9fff99662f504dce859bc855d5668282" - integrity sha512-TqnfW7hRTKje7UobBzXZJ2qOEDJvdcSVgVIK/fopC03xINFuFqQs8RVjyDT4ry7TmOo2ueAXwpXXXG4tNgtvoQ== + version "1.9.1" + resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.9.1.tgz#e3fec03e984a503718946c170db7d74556c2a187" + integrity sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw== dependencies: stream-chain "^2.2.5"