Skip to content

Conversation

@pahud
Copy link
Contributor

@pahud pahud commented Aug 21, 2025

Issue # (if applicable)

Closes #35292.

Reason for this change

This change addresses a security vulnerability in the ECS patterns where providing a custom load balancer would still result in the creation of overly permissive internet access rules, potentially bypassing user-intended security controls.

The Security Issue:
The openListener property controls whether CDK automatically creates security group ingress rules allowing internet traffic to reach the load balancer:

  • openListener: true (current default): CDK automatically creates an AWS::EC2::SecurityGroupIngress rule with CidrIp: '0.0.0.0/0', allowing anyone on the internet to access the load balancer on the listener port
  • openListener: false: CDK does not create automatic ingress rules, leaving security group management entirely to the user

The Problem:
Currently, openListener always defaults to true, regardless of whether users have provided custom load balancers with their own security groups. This creates a security gap where:

  1. Users carefully configure custom load balancers with restrictive security groups
  2. CDK still automatically adds 0.0.0.0/0 ingress rules, potentially bypassing the user's intended access controls
  3. The load balancer becomes accessible from the internet even when users intended to restrict access

Why This Matters:
When users provide custom load balancers, they typically want to manage security group rules themselves. The automatic creation of 0.0.0.0/0 rules can unintentionally expose services to the internet, creating a security vulnerability that users may not immediately notice.

Description of changes

This implementation adds a smart default mechanism for the openListener property in ApplicationLoadBalancedServiceBase that detects when users provide custom load balancers (which typically have custom security groups) and automatically defaults openListener to false for improved security.

Key changes made:

  • Smart Default Logic: Added detection for custom load balancers in ApplicationLoadBalancedServiceBase.ts
  • Feature Flag Protection: Implemented @aws-cdk/aws-ecs-patterns:smartDefaultOpenListener feature flag to ensure backward compatibility
  • Secure Default Behavior: When feature flag is enabled and custom load balancer is detected, openListener defaults to false instead of true
  • Override Capability: Users can still explicitly set openListener: true to override the smart default if needed
  • Comprehensive Testing: Added 5 new test cases covering all scenarios including backward compatibility

Technical implementation details:

  • The smart default logic checks if the feature flag is enabled and if a custom load balancer is provided
  • When both conditions are met, openListener defaults to false, preventing automatic creation of AWS::EC2::SecurityGroupIngress rules with CidrIp: '0.0.0.0/0'
  • When feature flag is disabled or no custom load balancer is provided, behavior remains unchanged (defaults to true)
  • The implementation uses existing CDK patterns and requires no new dependencies

CloudFormation Impact:

  • Before (or with openListener: true): CDK generates AWS::EC2::SecurityGroupIngress resources allowing internet access (CidrIp: '0.0.0.0/0')
  • After (with smart default openListener: false): No automatic ingress rules are created, users maintain full control over security group configuration

Design decisions made:

  • Feature Flag Approach: Chose feature flag implementation to ensure zero breaking changes for existing users
  • Custom Load Balancer Detection: Used props.loadBalancer !== undefined as the detection mechanism since custom load balancers typically indicate custom security group management
  • Explicit Override Support: Maintained ability for users to explicitly set openListener: true to override smart defaults when needed
  • Conservative Approach: Only applies smart default when feature flag is explicitly enabled, ensuring opt-in behavior

Alternatives considered and rejected:

  • Always-on behavior: Rejected due to potential breaking changes for existing users
  • Security group inspection: Rejected due to complexity and potential for false positives
  • Warning-only approach: Rejected as it doesn't actually fix the security vulnerability

Problem Description:

flowchart TD
    A[User Creates ECS Service] --> B[User Provides Custom Load Balancer<br/>with Custom Security Groups]
    B --> C[User Configures Restrictive Rules<br/>e.g., only VPC access]
    C --> D[CDK Always Defaults openListener = true]
    D --> E[CDK Creates 0.0.0.0/0 Ingress Rule<br/>⚠️ BYPASSES User's Security Intent]
    E --> F[🚨 Unintended Internet Exposure<br/>Security Vulnerability]
    
    style E fill:#ffebee
    style F fill:#ffcdd2
Loading

Smart Default Logic (Solution):

flowchart TD
    A[ECS Service Created] --> B{Feature Flag Enabled?}
    B -->|No| C[Legacy: openListener = true<br/>Creates 0.0.0.0/0 ingress rules]
    B -->|Yes| D{Custom Load Balancer Provided?}
    D -->|No| E[Default: openListener = true<br/>🌐 Creates 0.0.0.0/0 ingress rules]
    D -->|Yes| F[Smart Default: openListener = false<br/>🔒 No automatic ingress rules]
    
    style F fill:#e8f5e8
    style E fill:#fff3e0
    style C fill:#f5f5f5
Loading

Describe any new or updated permissions being added

N/A - This change does not introduce new IAM permissions or modify existing permission requirements. The change only affects the default behavior of security group rule creation, using existing ECS and ELB permissions.

Description of how you validated changes

Unit tests: Added comprehensive test coverage with 5 new test cases:

  • Smart default with custom load balancer (feature flag enabled) - verifies openListener defaults to false
  • Smart default without custom load balancer (feature flag enabled) - verifies openListener defaults to true
  • Explicit override with openListener: true (feature flag enabled) - verifies explicit values override smart defaults
  • Redirect listener behavior with smart defaults - verifies redirect functionality works with smart defaults
  • Backward compatibility test (feature flag disabled) - verifies no behavior change when feature flag is disabled

Integration tests: Created comprehensive integration test (integ.alb-fargate-service-smart-defaults.ts) that:

  • Deploys 4 different ECS service configurations to validate real AWS behavior
  • Uses AWS SDK calls to verify actual security group configurations
  • Confirms that custom security groups do not contain 0.0.0.0/0 ingress rules when smart defaults are applied
  • Validates that the feature works correctly in real AWS environments
  • Integration test results: Successfully deployed and all assertions passed

Manual validation:

  • Verified CloudFormation template generation with and without feature flag enabled
  • Confirmed that SecurityGroupIngress resources are not created when custom load balancers are used with smart defaults
  • Tested explicit openListener: true override functionality
  • Validated that existing behavior is unchanged when feature flag is disabled

Regression testing:

  • All existing unit tests continue to pass (226/226 tests passed)
  • Existing integration tests verified to ensure no functionality is broken
  • Confirmed backward compatibility by testing with feature flag disabled

Performance testing:

  • No performance impact - only adds a simple conditional check during construct creation
  • Build times and synthesis times remain unchanged

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added bug This issue is a bug. effort/medium Medium work item – several days of effort p1 labels Aug 21, 2025
@aws-cdk-automation aws-cdk-automation requested a review from a team August 21, 2025 13:10
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Aug 21, 2025
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review is outdated)

…m security groups

Adds smart default logic that automatically sets openListener to false when custom
load balancers are provided, preventing unintended creation of 0.0.0.0/0 ingress
rules when users have configured custom security groups.

- Add feature flag @aws-cdk/aws-ecs-patterns:smartDefaultOpenListener for backward compatibility
- Detect custom load balancers and default openListener to false for improved security
- Maintain explicit override capability with openListener: true
- Add comprehensive test coverage including integration tests
- Preserve backward compatibility when feature flag is disabled

Closes aws#35292
@pahud pahud changed the title chore(ecs_patterns): Set openListener: false when custom sg is provided chore(ecs_patterns): openListener should be false when custom sg is provided Aug 21, 2025
@aws-cdk-automation aws-cdk-automation dismissed their stale review August 21, 2025 17:25

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@pahud pahud marked this pull request as ready for review August 21, 2025 17:32
@pahud pahud changed the title chore(ecs_patterns): openListener should be false when custom sg is provided fix(ecs_patterns): openListener should be false when custom sg is provided Aug 21, 2025
@Abogical Abogical self-assigned this Aug 22, 2025
@pahud pahud requested a review from Abogical August 23, 2025 01:26
Copy link
Member

@Abogical Abogical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@mergify
Copy link
Contributor

mergify bot commented Aug 25, 2025

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit ccb1955 into aws:main Aug 25, 2025
20 of 21 checks passed
@github-actions
Copy link
Contributor

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 25, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bug This issue is a bug. contribution/core This is a PR that came from AWS. effort/medium Medium work item – several days of effort p1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ecs_patters: ECS pattern ApplicationLoadBalancedFargateService adding 0.0.0.0/0 access to security group

3 participants