Skip to content

Commit

Permalink
Add WAF ACL to Cognito User Pool (#976)
Browse files Browse the repository at this point in the history
### Feature or Bugfix
<!-- please choose -->
- Feature

### Detail
- Add WAF ACL to Cognito

### Relates
- #902

### Security
Please answer the questions below briefly where applicable, or write
`N/A`. Based on
[OWASP 10](https://owasp.org/Top10/en/).

- Does this PR introduce or modify any input fields or queries - this
includes
fetching data from storage outside the application (e.g. a database, an
S3 bucket)?
  - Is the input sanitized?
- What precautions are you taking before deserializing the data you
consume?
  - Is injection prevented by parametrizing queries?
  - Have you ensured no `eval` or similar functions are used?
- Does this PR introduce any functionality or component that requires
authorization?
- How have you ensured it respects the existing AuthN/AuthZ mechanisms?
  - Are you logging failed auth attempts?
- Are you using or adding any cryptographic features?
  - Do you use a standard proven implementations?
  - Are the used keys controlled by the customer? Where are they stored?
- Are you introducing any new policies/roles/users?
  - Have you used the least-privilege principle? How?


By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license.
  • Loading branch information
noah-paige authored Jan 24, 2024
1 parent a764c4a commit 72c4ff6
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 335 deletions.
160 changes: 2 additions & 158 deletions deploy/stacks/cloudfront.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from .pyNestedStack import pyNestedClass
from .solution_bundling import SolutionBundling
from .waf_rules import get_waf_rules

class CloudfrontDistro(pyNestedClass):
def __init__(
Expand Down Expand Up @@ -50,163 +51,6 @@ def __init__(
scope="CLOUDFRONT"
)

waf_rules = []
priority = 0
if custom_waf_rules:
if custom_waf_rules.get("allowed_geo_list"):
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='GeoMatch',
statement=wafv2.CfnWebACL.StatementProperty(
not_statement=wafv2.CfnWebACL.NotStatementProperty(
statement=wafv2.CfnWebACL.StatementProperty(
geo_match_statement=wafv2.CfnWebACL.GeoMatchStatementProperty(
country_codes=custom_waf_rules.get("allowed_geo_list")
)
)
)
),
action=wafv2.CfnWebACL.RuleActionProperty(block={}),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='GeoMatch',
),
priority=priority,
)
)
priority += 1
if custom_waf_rules.get("allowed_ip_list"):
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='IPMatch',
statement=wafv2.CfnWebACL.StatementProperty(
not_statement=wafv2.CfnWebACL.NotStatementProperty(
statement=wafv2.CfnWebACL.StatementProperty(
ip_set_reference_statement={
"arn" : ip_set_cloudfront.attr_arn
}
)
)
),
action=wafv2.CfnWebACL.RuleActionProperty(block={}),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='IPMatch',
),
priority=priority,
)
)
priority += 1
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesAdminProtectionRuleSet',
statement=wafv2.CfnWebACL.StatementProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS', name='AWSManagedRulesAdminProtectionRuleSet'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesAdminProtectionRuleSet',
),
priority=priority,
override_action=wafv2.CfnWebACL.OverrideActionProperty(none={}),
)
)
priority += 1
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesAmazonIpReputationList',
statement=wafv2.CfnWebACL.StatementProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS', name='AWSManagedRulesAmazonIpReputationList'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesAmazonIpReputationList',
),
priority=priority,
override_action=wafv2.CfnWebACL.OverrideActionProperty(none={}),
)
)
priority += 1
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesCommonRuleSet',
statement=wafv2.CfnWebACL.StatementProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS', name='AWSManagedRulesCommonRuleSet'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesCommonRuleSet',
),
priority=priority,
override_action=wafv2.CfnWebACL.OverrideActionProperty(none={}),
)
)
priority += 1
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesKnownBadInputsRuleSet',
statement=wafv2.CfnWebACL.StatementProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS', name='AWSManagedRulesKnownBadInputsRuleSet'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesKnownBadInputsRuleSet',
),
priority=priority,
override_action=wafv2.CfnWebACL.OverrideActionProperty(none={}),
)
)
priority += 1
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesLinuxRuleSet',
statement=wafv2.CfnWebACL.StatementProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS', name='AWSManagedRulesLinuxRuleSet'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesLinuxRuleSet',
),
priority=priority,
override_action=wafv2.CfnWebACL.OverrideActionProperty(none={}),
)
)
priority += 1
waf_rules.append(
wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesSQLiRuleSet',
statement=wafv2.CfnWebACL.StatementProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS', name='AWSManagedRulesSQLiRuleSet'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesSQLiRuleSet',
),
priority=priority,
override_action=wafv2.CfnWebACL.OverrideActionProperty(none={}),
)
)

acl = wafv2.CfnWebACL(
self,
'ACL-Cloudfront',
Expand All @@ -217,7 +61,7 @@ def __init__(
metric_name='waf-cloudfront',
sampled_requests_enabled=True,
),
rules=waf_rules,
rules=get_waf_rules(envname, 'Cloudfront', custom_waf_rules, ip_set_cloudfront),
)

logging_bucket = s3.Bucket(
Expand Down
38 changes: 38 additions & 0 deletions deploy/stacks/cognito.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
aws_cognito as cognito,
aws_ssm as ssm,
aws_iam as iam,
aws_wafv2 as wafv2,
aws_lambda as _lambda,
CfnOutput,
BundlingOptions,
Expand All @@ -14,6 +15,7 @@

from .pyNestedStack import pyNestedClass
from .solution_bundling import SolutionBundling
from .waf_rules import get_waf_rules


class IdpStack(pyNestedClass):
Expand All @@ -26,6 +28,7 @@ def __init__(
vpc=None,
prod_sizing=False,
internet_facing=True,
custom_waf_rules=None,
tooling_account_id=None,
enable_cw_rum=False,
cognito_user_session_timeout_inmins=43200,
Expand All @@ -50,6 +53,41 @@ def __init__(
cfn_user_pool.user_pool_add_ons = cognito.CfnUserPool.UserPoolAddOnsProperty(
advanced_security_mode='ENFORCED'
)

# Create IP set if IP filtering enabled in CDK.json
ip_set_regional = None
if custom_waf_rules and custom_waf_rules.get('allowed_ip_list'):
ip_set_regional = wafv2.CfnIPSet(
self,
'DataallRegionalIPSet-Cognito',
name=f'{resource_prefix}-{envname}-ipset-regional-cognito',
description=f'IP addresses allowed for Dataall {envname} Cognito User Pool',
addresses=custom_waf_rules.get('allowed_ip_list'),
ip_address_version='IPV4',
scope='REGIONAL',
)


acl = wafv2.CfnWebACL(
self,
'ACL-Cognito',
default_action=wafv2.CfnWebACL.DefaultActionProperty(allow={}),
scope='REGIONAL',
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
cloud_watch_metrics_enabled=True,
metric_name='waf-cognito',
sampled_requests_enabled=True,
),
rules=get_waf_rules(envname, 'Cognito', custom_waf_rules, ip_set_regional),
)

wafv2.CfnWebACLAssociation(
self,
'WafCognito',
resource_arn=self.user_pool.user_pool_arn,
web_acl_arn=acl.get_att('Arn').to_string(),
)

self.domain = cognito.UserPoolDomain(
self,
f'UserPool{envname}',
Expand Down
Loading

0 comments on commit 72c4ff6

Please sign in to comment.