Skip to content

Commit 561e9cd

Browse files
authored
Merge pull request #214 from aws-solutions/release/v2.1.4
release/v2.1.4
2 parents 32f4774 + 76e7495 commit 561e9cd

19 files changed

+206
-13
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.1.4] - 2024-11-18
9+
### Changed
10+
- Upgraded python runtimes in all control runbooks from python3.8 to python3.11.
11+
- Upgrade is done at build-time temporarily, until the `cdklabs/cdk-ssm-documents` package adds support for newer python runtimes.
12+
### Security
13+
- Upgraded cross-spawn to mitigate [CVE-2024-21538](https://avd.aquasec.com/nvd/cve-2024-21538)
14+
815
## [2.1.3] - 2024-09-18
916

1017
### Fixed

deployment/build-s3-dist.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ main() {
181181
mv "$template_dist_dir"/MemberRoleStack.template "$template_dist_dir"/aws-sharr-member-roles.template
182182

183183
rm "$template_dist_dir"/*.nested.template
184+
185+
python3 $template_dir/upgrade_python_runtimes.py $template_dist_dir/playbooks
184186
}
185187

186188
main "$@"

deployment/upgrade_python_runtimes.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# !/usr/bin/env python3
5+
6+
import json
7+
import os
8+
import re
9+
import sys
10+
11+
12+
def update_python_runtimes(directory):
13+
"""
14+
The @cdklabs/cdk-ssm-documents package used to create some of the solution's control runbooks (SSM Documents)
15+
does not support python runtimes newer than python3.8 as of 11/14/2024. This function updates all member runbook templates
16+
to use python3.11 instead of python3.8 after they are synthesized.
17+
:param directory: directory where synthesized templates are located.
18+
"""
19+
for template_filename in os.listdir(directory):
20+
if re.search(r"MemberStack(\d*).template$", template_filename):
21+
file_path = os.path.join(directory, template_filename)
22+
23+
with open(file_path, "r") as file:
24+
try:
25+
data = json.load(file)
26+
except json.JSONDecodeError:
27+
print(f"Skipping {template_filename}: not a valid JSON file.")
28+
continue
29+
# Convert template JSON to string and replace "python3.8" with "python3.11"
30+
template_str = json.dumps(data)
31+
updated_template_str = template_str.replace("python3.8", "python3.11")
32+
updated_template = json.loads(updated_template_str)
33+
# Write the updated template back to the .template file
34+
with open(file_path, "w") as file:
35+
json.dump(updated_template, file, indent=1)
36+
print(
37+
f"Successfully updated python runtimes in {template_filename} from python3.8 --> python3.11"
38+
)
39+
40+
41+
if __name__ == "__main__":
42+
if len(sys.argv) != 2:
43+
print(
44+
"Invalid invocation. Script should be invoked like: python upgrade_python_runtimes.py <directory_path>"
45+
)
46+
sys.exit(1)
47+
directory_path = sys.argv[1]
48+
update_python_runtimes(directory_path)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "automated_security_response_on_aws"
3-
version = "2.1.3"
3+
version = "2.1.4"
44

55
[tool.setuptools]
66
package-dir = {"" = "source"}

solution-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
id: SO0111
22
name: security-hub-automated-response-and-remediation
3-
version: 2.1.3
3+
version: 2.1.4
44
cloudformation_templates:
55
- template: aws-sharr-deploy.template
66
main_template: true

source/lib/__snapshots__/member-stack.test.ts.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,14 @@ exports[`member stack snapshot matches 1`] = `
12651265
"DependsOn": [
12661266
"WaitProviderRole83B0295F",
12671267
],
1268+
"Metadata": {
1269+
"guard": {
1270+
"SuppressedRules": [
1271+
"LAMBDA_CONCURRENCY_CHECK",
1272+
"LAMBDA_INSIDE_VPC",
1273+
],
1274+
},
1275+
},
12681276
"Properties": {
12691277
"Code": {
12701278
"S3Bucket": {
@@ -1307,6 +1315,12 @@ exports[`member stack snapshot matches 1`] = `
13071315
},
13081316
],
13091317
},
1318+
"guard": {
1319+
"SuppressedRules": [
1320+
"IAM_NO_INLINE_POLICY_CHECK",
1321+
"IAM_POLICYDOCUMENT_NO_WILDCARD_RESOURCE",
1322+
],
1323+
},
13101324
},
13111325
"Properties": {
13121326
"AssumeRolePolicyDocument": {

source/lib/cdk-helper/add-cfn-nag-suppression.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,24 @@ export function addCfnNagSuppression(resource: IConstruct, suppression: CfnNagSu
2424
};
2525
}
2626
}
27+
28+
export function addCfnGuardSuppression(resource: IConstruct, suppression: string): void {
29+
const cfnResource = resource.node.defaultChild as CfnResource;
30+
if (!cfnResource?.cfnOptions) {
31+
throw new Error(`Resource ${cfnResource?.logicalId} has no cfnOptions, unable to add CfnGuard suppression`);
32+
}
33+
const existingSuppressions: string[] = cfnResource.cfnOptions.metadata?.guard?.SuppressedRules;
34+
if (existingSuppressions) {
35+
existingSuppressions.push(suppression);
36+
} else if (cfnResource.cfnOptions.metadata) {
37+
cfnResource.cfnOptions.metadata.guard = {
38+
SuppressedRules: [suppression],
39+
};
40+
} else {
41+
cfnResource.cfnOptions.metadata = {
42+
guard: {
43+
SuppressedRules: [suppression],
44+
},
45+
};
46+
}
47+
}

source/lib/cloudwatch_metrics.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Topic } from 'aws-cdk-lib/aws-sns';
1919
import { Key } from 'aws-cdk-lib/aws-kms';
2020
import { SnsAction } from 'aws-cdk-lib/aws-cloudwatch-actions';
2121
import { ServicePrincipal } from 'aws-cdk-lib/aws-iam';
22+
import { addCfnGuardSuppression } from './cdk-helper/add-cfn-nag-suppression';
2223

2324
export interface CloudWatchMetricsProps {
2425
solutionId: string;
@@ -195,6 +196,7 @@ export class CloudWatchMetrics {
195196
});
196197
setCondition(noRemediationErrorAlarm, isUsingCloudWatchMetricsAlarms);
197198
noRemediationErrorAlarm.addAlarmAction(new SnsAction(snsAlarmTopic));
199+
addCfnGuardSuppression(noRemediationErrorAlarm, 'CFN_NO_EXPLICIT_RESOURCE_NAMES');
198200

199201
const failedAssumeRoleAlarm = failedAssumeRoleMetric.createAlarm(scope, 'FailedAssumeRoleAlarm', {
200202
alarmName: 'ASR-RunbookAssumeRoleFailure',
@@ -210,6 +212,8 @@ export class CloudWatchMetrics {
210212
setCondition(failedAssumeRoleAlarm, isUsingCloudWatchMetricsAlarms);
211213
failedAssumeRoleAlarm.addAlarmAction(new SnsAction(snsAlarmTopic));
212214

215+
addCfnGuardSuppression(failedAssumeRoleAlarm, 'CFN_NO_EXPLICIT_RESOURCE_NAMES');
216+
213217
const stateMachineExecutionsAlarm = stateMachineExecutionsMetric.createAlarm(scope, 'StateMachineExecutions', {
214218
alarmName: 'ASR-StateMachineExecutions',
215219
evaluationPeriods: 1,
@@ -222,6 +226,7 @@ export class CloudWatchMetrics {
222226

223227
setCondition(stateMachineExecutionsAlarm, isUsingCloudWatchMetricsAlarms);
224228
stateMachineExecutionsAlarm.addAlarmAction(new SnsAction(snsAlarmTopic));
229+
addCfnGuardSuppression(stateMachineExecutionsAlarm, 'CFN_NO_EXPLICIT_RESOURCE_NAMES');
225230

226231
/// CloudWatch Dashboard
227232
const remediationDashboard = new Dashboard(scope, 'RemediationDashboard', {

source/lib/common-orchestrator-construct.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Construct } from 'constructs';
1010
import * as cdk_nag from 'cdk-nag';
1111
import { Timeout } from 'aws-cdk-lib/aws-stepfunctions';
1212
import { IQueue } from 'aws-cdk-lib/aws-sqs';
13+
import { addCfnGuardSuppression } from './cdk-helper/add-cfn-nag-suppression';
1314

1415
export interface ConstructProps {
1516
roleArn: string;
@@ -494,6 +495,7 @@ export class OrchestratorConstruct extends Construct {
494495
'CloudWatch Logs permissions require resource * except for DescribeLogGroups, except for GovCloud, which only works with resource *',
495496
},
496497
]);
498+
addCfnGuardSuppression(orchestratorRole, 'IAM_NO_INLINE_POLICY_CHECK');
497499

498500
const orchestratorStateMachine = new sfn.StateMachine(this, 'StateMachine', {
499501
definitionBody: sfn.DefinitionBody.fromChainable(extractFindings),

source/lib/orchestrator_roles-construct.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
CfnRole,
1313
} from 'aws-cdk-lib/aws-iam';
1414
import { Construct } from 'constructs';
15+
import { addCfnGuardSuppression } from './cdk-helper/add-cfn-nag-suppression';
1516

1617
export interface OrchRoleProps {
1718
solutionId: string;
@@ -142,5 +143,6 @@ export class OrchestratorMemberRole extends Construct {
142143
],
143144
},
144145
};
146+
addCfnGuardSuppression(memberRole, 'IAM_NO_INLINE_POLICY_CHECK');
145147
}
146148
}

0 commit comments

Comments
 (0)