Created
April 21, 2022 12:11
-
-
Save iann0036/6e1cab8a55bf0322a86f3ee780292886 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SecurityHubStandardsConfigurationStackSet: | |
DependsOn: | |
- SecurityStackSet | |
Condition: IsDelegationComplete | |
Type: AWS::CloudFormation::StackSet | |
Properties: | |
StackSetName: securityhub-standards | |
PermissionModel: SERVICE_MANAGED | |
CallAs: DELEGATED_ADMIN | |
Capabilities: | |
- CAPABILITY_NAMED_IAM | |
ManagedExecution: | |
Active: true | |
AutoDeployment: | |
Enabled: true | |
RetainStacksOnAccountRemoval: false | |
StackInstancesGroup: | |
- DeploymentTargets: | |
OrganizationalUnitIds: | |
- !Ref OrganizationRootId | |
Regions: | |
- us-east-1 | |
TemplateBody: | | |
Resources: | |
SecurityHubStandardsRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Action: sts:AssumeRole | |
Effect: Allow | |
Principal: | |
Service: lambda.amazonaws.com | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole | |
Policies: | |
- PolicyName: root | |
PolicyDocument: | |
Statement: | |
- Effect: Allow | |
Action: | |
- securityhub:BatchEnableStandards | |
- securityhub:BatchDisableStandards | |
- securityhub:UpdateStandardsControl | |
- securityhub:GetEnabledStandards | |
- securityhub:DescribeStandardsControls | |
Resource: '*' | |
SecurityHubStandardsLambda: | |
Type: AWS::Lambda::Function | |
Properties: | |
Handler: index.handler | |
Role: !GetAtt SecurityHubStandardsRole.Arn | |
Runtime: python3.7 | |
Timeout: 600 | |
Code: | |
ZipFile: | | |
import json | |
import os | |
import cfnresponse | |
import boto3 | |
import pprint | |
import traceback | |
from botocore.config import Config | |
def handler(event, context): | |
pprint.pprint(event) | |
longretriesconfig = Config( | |
retries = { | |
'max_attempts': 10, | |
'mode': 'standard' | |
} | |
) | |
try: | |
returndata = {} | |
regions = ['ap-southeast-2', 'us-east-1', 'ap-southeast-1'] | |
if event['ResourceType'] == 'Custom::SecurityHubStandards' and event['RequestType'] == 'Create': | |
for region in regions: | |
client = boto3.client('securityhub', region_name=region, config=longretriesconfig) | |
client.batch_enable_standards( | |
StandardsSubscriptionRequests=[ | |
{ | |
'StandardsArn': 'arn:aws:securityhub:' + region + '::standards/pci-dss/v/3.2.1' | |
} | |
] | |
) | |
if event['ResourceType'] == 'Custom::SecurityHubStandards' and (event['RequestType'] == 'Create' or event['RequestType'] == 'Update'): | |
for region in regions: | |
client = boto3.client('securityhub', region_name=region, config=longretriesconfig) | |
for standard in client.get_enabled_standards()['StandardsSubscriptions']: | |
paginator = client.get_paginator('describe_standards_controls') | |
pages = paginator.paginate( | |
StandardsSubscriptionArn=standard['StandardsSubscriptionArn'] | |
) | |
for page in pages: | |
for control in page['Controls']: | |
for disabledcontrol in event['ResourceProperties']['DisabledControls']: | |
if control['ControlId'] in disabledcontrol['ControlIDs'] and region not in disabledcontrol['RegionExceptions']: | |
client.update_standards_control( | |
StandardsControlArn=control['StandardsControlArn'], | |
ControlStatus='DISABLED', | |
DisabledReason=disabledcontrol['Reason'] | |
) | |
elif event['ResourceType'] == 'Custom::SecurityHubStandards' and event['RequestType'] == 'Delete': | |
for region in regions: | |
client = boto3.client('securityhub', region_name=region) | |
for standard in client.get_enabled_standards()['StandardsSubscriptions']: | |
if standard['StandardsArn'] == 'arn:aws:securityhub:' + region + '::standards/pci-dss/v/3.2.1': | |
client.batch_disable_standards( | |
StandardsSubscriptionArns=[ | |
standard['StandardsSubscriptionArn'] | |
] | |
) | |
except Exception as e: | |
pprint.pprint(e) | |
traceback.print_stack() | |
cfnresponse.send(event, context, cfnresponse.FAILED, returndata, "SecurityHubStandardsInvocation") | |
return | |
cfnresponse.send(event, context, cfnresponse.SUCCESS, returndata, "SecurityHubStandardsInvocation") | |
SecurityHubStandards: | |
Type: Custom::SecurityHubStandards | |
Properties: | |
ServiceToken: !GetAtt SecurityHubStandardsLambda.Arn | |
DisabledControls: | |
- Reason: Disabled for all regions except us-east-1 due to global-only control. | |
ControlIDs: ['IAM.3', 'IAM.4', 'IAM.5', 'IAM.8', 'CIS.1.2', 'CIS.1.3', 'CIS.1.4', 'CIS.1.12', 'CIS.1.16', 'CIS.1.20', 'CIS.1.22', 'PCI.IAM.1', 'PCI.IAM.2', 'PCI.IAM.3', 'PCI.IAM.6', 'Config.1', 'CIS.2.5', 'PCI.Config.1'] | |
RegionExceptions: ['us-east-1'] | |
- Reason: Disabled due to SCP in place to prevent IAM user usage. | |
ControlIDs: ['IAM.7', 'CIS.1.5', 'CIS.1.6', 'CIS.1.7', 'CIS.1.8', 'CIS.1.9', 'CIS.1.10', 'CIS.1.11'] | |
RegionExceptions: [] | |
- Reason: Disabled due to SCP in place to prevent root user usage. | |
ControlIDs: ['IAM.6', 'CIS.1.13', 'CIS.1.14', 'PCI.IAM.4', 'PCI.IAM.5'] | |
RegionExceptions: [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment