Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(HIPAA Security): DMS check #341

Merged
merged 3 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,13 @@ There are currently no warnings for this rule pack.
| [HIPAA.Security-CodeBuildProjectSourceRepoUrl](https://docs.aws.amazon.com/config/latest/developerguide/codebuild-project-source-repo-url-check.html) | The Codebuild project which utilizes either a GitHub or BitBucket repository does not utilize OAUTH. | OAUTH is the most secure method of authenticating your Codebuild application. Use OAuth instead of personal access tokens or a user name and password to grant authorization for accessing GitHub or Bitbucket repositories. | 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1) |
| [HIPAA.Security-CloudWatchAlarmAction](https://docs.aws.amazon.com/config/latest/developerguide/cloudwatch-alarm-action-check.html) | The CloudWatch alarm does not have at least one alarm action, one INSUFFICIENT_DATA action, or one OK action enabled. | Amazon CloudWatch alarms alert when a metric breaches the threshold for a specified number of evaluation periods. The alarm performs one or more actions based on the value of the metric or expression relative to a threshold over a number of time periods. | 164.312(b) |
| [HIPAA.Security-CloudWatchLogGroupEncrypted](https://docs.aws.amazon.com/config/latest/developerguide/cloudwatch-log-group-encrypted.html) | The CloudWatch Log Group is not encrypted with an AWS KMS key. | To help protect sensitive data at rest, ensure encryption is enabled for your Amazon CloudWatch Log Groups. | 164.312(a)(2)(iv), 164.312(e)(2)(ii) |
| [HIPAA.Security-DMSReplicationNotPublic](https://docs.aws.amazon.com/config/latest/developerguide/dms-replication-not-public.html) | The DMS replication instance is public. | DMS replication instances can contain sensitive information and access control is required for such accounts. | 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1) |
| [HIPAA.Security-EC2InstanceDetailedMonitoringEnabled](https://docs.aws.amazon.com/config/latest/developerguide/ec2-instance-detailed-monitoring-enabled.html) | The EC2 instance does not have detailed monitoring enabled. | Enable this rule to help improve Amazon Elastic Compute Cloud (Amazon EC2) instance monitoring on the Amazon EC2 console, which displays monitoring graphs with a 1-minute period for the instance. | 164.312(b) |
| [HIPAA.Security-EC2InstanceNoPublicIp](https://docs.aws.amazon.com/config/latest/developerguide/ec2-instance-no-public-ip.html) | The EC2 instance is associated with a public IP address. | Manage access to the AWS Cloud by ensuring Amazon Elastic Compute Cloud (Amazon EC2) instances cannot be publicly accessed. Amazon EC2 instances can contain sensitive information and access control is required for such accounts. | 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1) |
| [HIPAA.Security-EC2InstancesInVPC](https://docs.aws.amazon.com/config/latest/developerguide/ec2-instances-in-vpc.html) | The EC2 instance is not within a VPC. | Deploy Amazon Elastic Compute Cloud (Amazon EC2) instances within an Amazon Virtual Private Cloud (Amazon VPC) to enable secure communication between an instance and other services within the amazon VPC, without requiring an internet gateway, NAT device, or VPN connection. All traffic remains securely within the AWS Cloud. Because of their logical isolation, domains that reside within anAmazon VPC have an extra layer of security when compared to domains that use public endpoints. Assign Amazon EC2 instances to an Amazon VPC to properly manage access. | 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1) |



### Excluded Rules

Unimplemented rules from the AWS HIPAA Security Conformance Pack.
Expand Down
30 changes: 22 additions & 8 deletions src/HIPAA-Security/hipaa-security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
hipaaSecurityCloudTrailEncryptionEnabled,
hipaaSecurityCloudTrailLogFileValidationEnabled,
} from './rules/cloudtrail';
import { hipaaSecurityDMSReplicationNotPublic } from './rules/dms';
import {
hipaaSecurityCloudWatchAlarmAction,
hipaaSecurityCloudWatchLogGroupEncrypted,
Expand All @@ -46,11 +47,10 @@ export class HIPAASecurityChecks extends NagPack {
this.checkAPIGW(node, ignores);
this.checkAutoScaling(node, ignores);
this.checkCloudTrail(node, ignores);
// this.checkCloudWatch(node, ignores);
this.checkCodeBuild(node, ignores);
this.checkCloudWatch(node, ignores);
// this.checkCodeBuild(node, ignores);
// this.checkDMS(node, ignores);
this.checkDMS(node, ignores);
// this.checkDynamoDB(node, ignores);
this.checkEC2(node, ignores);
// this.checkECS(node, ignores);
Expand Down Expand Up @@ -305,12 +305,26 @@ export class HIPAASecurityChecks extends NagPack {
}
}

// /**
// * Check DMS Resources
// * @param node the IConstruct to evaluate
// * @param ignores list of ignores for the resource
// */
// private checkDMS(node: CfnResource, ignores: any): void {}
/**
* Check DMS Resources
* @param node the IConstruct to evaluate
* @param ignores list of ignores for the resource
*/
private checkDMS(node: CfnResource, ignores: any) {
if (
!this.ignoreRule(ignores, 'HIPAA.Security-DMSReplicationNotPublic') &&
!hipaaSecurityDMSReplicationNotPublic(node)
) {
const ruleId = 'HIPAA.Security-DMSReplicationNotPublic';
const info =
'The DMS replication instance is public - (Control IDs: 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1)).';
const explanation =
'DMS replication instances can contain sensitive information and access control is required for such accounts.';
Annotations.of(node).addError(
this.createMessage(ruleId, info, explanation)
);
}
}

// /**
// * Check DynamoDB Resources
Expand Down
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 { CfnReplicationInstance } from '@aws-cdk/aws-dms';
import { CfnResource, Stack } from '@aws-cdk/core';

/**
* DMS replication instances are not public - (Control IDs: 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1))
* @param node the CfnResource to check
*/
export default function (node: CfnResource): boolean {
if (node instanceof CfnReplicationInstance) {
const publicAccess = Stack.of(node).resolve(node.publiclyAccessible);
if (publicAccess !== false) {
return false;
}
}
return true;
}
1 change: 1 addition & 0 deletions src/HIPAA-Security/rules/dms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
export { default as hipaaSecurityDMSReplicationNotPublic } from './hipaaSecurityDMSReplicationNotPublic';
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CfnResource, Stack } from '@aws-cdk/core';
export default function (node: CfnResource): boolean {
if (node instanceof CfnReplicationInstance) {
const publicAccess = Stack.of(node).resolve(node.publiclyAccessible);
if (!(publicAccess === false)) {
if (publicAccess !== false) {
return false;
}
}
Expand Down
46 changes: 46 additions & 0 deletions test/HIPAA-Security/HIPAA-Security-DMS.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

import { SynthUtils } from '@aws-cdk/assert';
import { CfnReplicationInstance } from '@aws-cdk/aws-dms';
import { Aspects, Stack } from '@aws-cdk/core';
import { HIPAASecurityChecks } from '../../src';

describe('AWS Database Migration Service (AWS DMS)', () => {
test('hipaaSecurityDMSReplicationNotPublic: DMS replication instances are not public - (Control IDs: 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1))', () => {
const positive = new Stack();
Aspects.of(positive).add(new HIPAASecurityChecks());
new CfnReplicationInstance(positive, 'rInstance', {
replicationInstanceClass: 'dms.t2.micro',
});
const messages = SynthUtils.synthesize(positive).messages;
expect(messages).toContainEqual(
expect.objectContaining({
entry: expect.objectContaining({
data: expect.stringContaining(
'HIPAA.Security-DMSReplicationNotPublic:'
),
}),
})
);

const negative = new Stack();
Aspects.of(negative).add(new HIPAASecurityChecks());
new CfnReplicationInstance(negative, 'rInstance', {
replicationInstanceClass: 'dms.t2.micro',
publiclyAccessible: false,
});
const messages2 = SynthUtils.synthesize(negative).messages;
expect(messages2).not.toContainEqual(
expect.objectContaining({
entry: expect.objectContaining({
data: expect.stringContaining(
'HIPAA.Security-DMSReplicationNotPublic:'
),
}),
})
);
});
});
2 changes: 1 addition & 1 deletion test/NIST-800-53/NIST-800-53-DMS.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Aspects, Stack } from '@aws-cdk/core';
import { NIST80053Checks } from '../../src';

describe('AWS Database Migration Service (AWS DMS)', () => {
test('nist80053DMSReplication: DMS replication instances are not public - (Control ID: AC-4)', () => {
test('nist80053DMSReplicationNotPublic: DMS replication instances are not public - (Control ID: AC-4)', () => {
const positive = new Stack();
Aspects.of(positive).add(new NIST80053Checks());
new CfnReplicationInstance(positive, 'rInstance', {
Expand Down