Skip to content

Commit

Permalink
feat(HIPAA Security): API Gateway Rules (#323)
Browse files Browse the repository at this point in the history
Closes #160 
Closes #161 
Closes #162 
Closes #163 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
dontirun authored Aug 26, 2021
1 parent 2a27b91 commit bd72956
Show file tree
Hide file tree
Showing 13 changed files with 387 additions and 21 deletions.
22 changes: 13 additions & 9 deletions RULES.md

Large diffs are not rendered by default.

79 changes: 72 additions & 7 deletions src/HIPAA-Security/hipaa-security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ SPDX-License-Identifier: Apache-2.0

import { Annotations, CfnResource, IConstruct } from '@aws-cdk/core';
import { NagPack } from '../common';
import {
hipaaSecurityAPIGWCacheEnabledAndEncrypted,
hipaaSecurityAPIGWExecutionLoggingEnabled,
hipaaSecurityAPIGWSSLEnabled,
hipaaSecurityAPIGWXrayEnabled,
} from './rules/apigw';
import {
hipaaSecurityCloudTrailCloudWatchLogsEnabled,
hipaaSecurityCloudTrailEncryptionEnabled,
Expand All @@ -26,7 +32,7 @@ export class HIPAASecurityChecks extends NagPack {
if (node instanceof CfnResource) {
// Get ignores metadata if it exists
const ignores = node.getMetadata('cdk_nag')?.rules_to_suppress;
// this.checkAPIGW(node, ignores);
this.checkAPIGW(node, ignores);
// this.checkAutoScaling(node, ignores);
this.checkCloudTrail(node, ignores);
// this.checkCloudWatch(node, ignores);
Expand All @@ -53,12 +59,71 @@ export class HIPAASecurityChecks extends NagPack {
}
}

// /**
// * Check API Gateway Resources
// * @param node the IConstruct to evaluate
// * @param ignores list of ignores for the resource
// */
// private checkAPIGW(node: CfnResource, ignores: any): void {}
/**
* Check API Gateway Resources
* @param node the IConstruct to evaluate
* @param ignores list of ignores for the resource
*/
private checkAPIGW(node: CfnResource, ignores: any): void {
if (
!this.ignoreRule(
ignores,
'HIPAA.Security-APIGWCacheEnabledAndEncrypted'
) &&
!hipaaSecurityAPIGWCacheEnabledAndEncrypted(node)
) {
const ruleId = 'HIPAA.Security-APIGWCacheEnabledAndEncrypted';
const info =
'The API Gateway stage does not have caching enabled and encrypted for all methods - (Control IDs: 164.312(a)(2)(iv), 164.312(e)(2)(ii)).';
const explanation =
"To help protect data at rest, ensure encryption is enabled for your API Gateway stage's cache. Because sensitive data can be captured for the API method, enable encryption at rest to help protect that data.";
Annotations.of(node).addError(
this.createMessage(ruleId, info, explanation)
);
}
if (
!this.ignoreRule(
ignores,
'HIPAA.Security-APIGWExecutionLoggingEnabled'
) &&
!hipaaSecurityAPIGWExecutionLoggingEnabled(node)
) {
const ruleId = 'HIPAA.Security-APIGWExecutionLoggingEnabled';
const info =
'The API Gateway stage does not have execution logging enabled for all methods - (Control ID: 164.312(b)).';
const explanation =
'API Gateway logging displays detailed views of users who accessed the API and the way they accessed the API. This insight enables visibility of user activities.';
Annotations.of(node).addError(
this.createMessage(ruleId, info, explanation)
);
}
if (
!this.ignoreRule(ignores, 'HIPAA.Security-APIGWSSLEnabled') &&
!hipaaSecurityAPIGWSSLEnabled(node)
) {
const ruleId = 'HIPAA.Security-APIGWSSLEnabled';
const info =
'The API Gateway REST API stage is not configured with SSL certificates - (Control IDs: 164.312(a)(2)(iv), 164.312(e)(1), 164.312(e)(2)(i), 164.312(e)(2)(ii)).';
const explanation =
'Ensure Amazon API Gateway REST API stages are configured with SSL certificates to allow backend systems to authenticate that requests originate from API Gateway.';
Annotations.of(node).addError(
this.createMessage(ruleId, info, explanation)
);
}
if (
!this.ignoreRule(ignores, 'HIPAA.Security-APIGWXrayEnabled') &&
!hipaaSecurityAPIGWXrayEnabled(node)
) {
const ruleId = 'HIPAA.Security-APIGWXrayEnabled';
const info =
'The API Gateway REST API stage does not have X-Ray enabled - (Control ID: 164.312(b)).';
const explanation =
'AWS X-Ray collects data about requests that your application serves, and provides tools you can use to view, filter, and gain insights into that data to identify issues and opportunities for optimization. Ensure X-Ray is enables so you can see detailed information not only about the request and response, but also about calls that your application makes to downstream AWS resources, microservices, databases and HTTP web APIs.';
Annotations.of(node).addError(
this.createMessage(ruleId, info, explanation)
);
}
}

// /**
// * Check Auto Scaling Resources
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { IConstruct, Stack } from '@aws-cdk/core';

/**
* All methods in API Gateway stages have caching enabled and encrypted - (Control IDs: 164.312(a)(2)(iv), 164.312(e)(2)(ii))
* @param node the CfnResource to check
*/
export default function (node: IConstruct): boolean {
if (node instanceof CfnStage) {
if (node.methodSettings == undefined) {
return false;
}
const methodSettings = Stack.of(node).resolve(node.methodSettings);
let found = false;
for (const setting of methodSettings) {
const resolvedSetting = Stack.of(node).resolve(setting);
if (
resolvedSetting?.httpMethod == '*' &&
resolvedSetting?.resourcePath == '/*' &&
resolvedSetting?.cacheDataEncrypted &&
resolvedSetting?.cachingEnabled
) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
import { CfnStage, MethodLoggingLevel } from '@aws-cdk/aws-apigateway';
import { IConstruct, Stack } from '@aws-cdk/core';

/**
* API Gateway stages have logging enabled - (Control ID: 164.312(b))
* @param node the CfnResource to check
*/
export default function (node: IConstruct): boolean {
if (node instanceof CfnStage) {
if (node.methodSettings == undefined) {
return false;
}
const methodSettings = Stack.of(node).resolve(node.methodSettings);
let found = false;
for (const setting of methodSettings) {
const resolvedSetting = Stack.of(node).resolve(setting);
if (
resolvedSetting?.httpMethod == '*' &&
resolvedSetting?.resourcePath == '/*' &&
(resolvedSetting?.loggingLevel == MethodLoggingLevel.ERROR ||
resolvedSetting?.loggingLevel == MethodLoggingLevel.INFO)
) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
19 changes: 19 additions & 0 deletions src/HIPAA-Security/rules/apigw/hipaaSecurityAPIGWSSLEnabled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { IConstruct } from '@aws-cdk/core';

/**
* API Gateway REST API stages are configured with SSL certificates - (Control IDs: 164.312(a)(2)(iv), 164.312(e)(1), 164.312(e)(2)(i), 164.312(e)(2)(ii))
* @param node the CfnResource to check
*/
export default function (node: IConstruct): boolean {
if (node instanceof CfnStage) {
if (node.clientCertificateId == undefined) {
return false;
}
}
return true;
}
20 changes: 20 additions & 0 deletions src/HIPAA-Security/rules/apigw/hipaaSecurityAPIGWXrayEnabled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { IConstruct, Stack } from '@aws-cdk/core';

/**
* API Gateway REST API stages have X-Ray tracing enabled - (Control IDs: 164.312(b))
* @param node the CfnResource to check
*/
export default function (node: IConstruct): boolean {
if (node instanceof CfnStage) {
const tracingEnabled = Stack.of(node).resolve(node.tracingEnabled);
if (tracingEnabled !== true) {
return false;
}
}
return true;
}
4 changes: 4 additions & 0 deletions src/HIPAA-Security/rules/apigw/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
export { default as hipaaSecurityAPIGWCacheEnabledAndEncrypted } from './hipaaSecurityAPIGWCacheEnabledAndEncrypted';
export { default as hipaaSecurityAPIGWExecutionLoggingEnabled } from './hipaaSecurityAPIGWExecutionLoggingEnabled';
export { default as hipaaSecurityAPIGWSSLEnabled } from './hipaaSecurityAPIGWSSLEnabled';
export { default as hipaaSecurityAPIGWXrayEnabled } from './hipaaSecurityAPIGWXrayEnabled';
2 changes: 1 addition & 1 deletion src/NIST-800-53/nist-800-53.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class NIST80053Checks extends NagPack {
) {
const ruleId = 'NIST.800.53-APIGWCacheEnabledAndEncrypted';
const info =
'The API Gateway stage does not have caching enabled and encrypted for all methods - (Control IDs: SC-13, SC-28).';
'The API Gateway stage does not have caching enabled and encrypted for all methods - (Control IDs: SC-13, SC-28).';
const explanation =
"To help protect data at rest, ensure encryption is enabled for your API Gateway stage's cache. Because sensitive data can be captured for the API method, enable encryption at rest to help protect that data.";
Annotations.of(node).addError(
Expand Down
Loading

0 comments on commit bd72956

Please sign in to comment.