Skip to content

Feature/aws container services#1719

Open
philipwubbleyou wants to merge 6 commits intonccgroup:masterfrom
philipwubbleyou:feature/aws-container-services
Open

Feature/aws container services#1719
philipwubbleyou wants to merge 6 commits intonccgroup:masterfrom
philipwubbleyou:feature/aws-container-services

Conversation

@philipwubbleyou
Copy link

@philipwubbleyou philipwubbleyou commented Nov 14, 2025

Description

This PR adds support for scanning AWS container services (ECS, ECR, EKS) and includes critical bug fixes discovered during testing and integration.

Fixes #1491
Based on the excellent work by @kedar1704 in #1587

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Summary of Changes

New Services Added

  • ECR (Elastic Container Registry): Repository scanning, image scanning configuration, tag immutability checks
  • ECS (Elastic Container Service): Cluster configuration, services, tasks, Container Insights monitoring
  • EKS (Elastic Kubernetes Service): Cluster configuration, node groups, logging, endpoint access controls

Bug Fixes

1. ECS Service/Task ARN Parsing (ScoutSuite/providers/aws/facade/ecs.py)

Problem: Code attempted to determine cluster ownership by listing ALL clusters and concatenating ARNs with "".join(), resulting in malformed cluster identifiers.

Error: InvalidParameterException: Unsupported resource type: cluster

Fix: Extract cluster name directly from ARN structure:

  • Service ARN: arn:aws:ecs:region:account:service/cluster-name/service-name
  • Task ARN: arn:aws:ecs:region:account:task/cluster-name/task-id
  • Extract: cluster_name = arn.split('/')[1]

2. ECS Optional Field Handling

Problem: Code assumed all tasks have containerInstanceArn and all services have launchType, causing KeyError exceptions.

Root Cause:

  • Fargate tasks lack containerInstanceArn (only present for EC2 launch type)
  • Services using capacity provider strategies may not have launchType

Fix: Changed all field access to use .get() with appropriate defaults

Files:

  • ScoutSuite/providers/aws/resources/ecs/tasks.py
  • ScoutSuite/providers/aws/resources/ecs/services.py

3. RDS Snapshot Error Handling (ScoutSuite/providers/aws/facade/rds.py)

Problem: TypeError when checking exception type:

if 'DBSnapshotNotFound' in e:  # e is ClientError object
    TypeError: argument of type 'ClientError' is not iterable

Fix:

error_message = str(e)
if 'DBSnapshotNotFound' in error_message:

Also added proper handling for AWS Throttling errors with warning-level logging instead of exceptions.

4. Service Initialization Conflicts

Problem: ECR/ECS/EKS were initialized twice (standard + proprietary), causing resource conflicts

Fix: Removed duplicate initialization from proprietary services section

Files:

  • ScoutSuite/providers/aws/services.py
  • ScoutSuite/providers/aws/facade/base.py

5. Missing Async/Await Keywords

Problem: Several async operations lacked await, causing synchronous execution

Fix: Added await to all async calls in ECS/ECR facades

Files:

  • ScoutSuite/providers/aws/facade/ecs.py
  • ScoutSuite/providers/aws/facade/ecr.py

Security Rules Added

ECR (2 rules)

  • ecr-image-scanning-enabled: Verifies image scanning on push is enabled
  • ecr-tag-immutability-enabled: Checks tag immutability configuration

ECS (1 rule)

  • ecs-container-insights-enabled: Validates Container Insights is enabled for monitoring

EKS (2 rules)

  • eks-cluster-logging-enabled: Ensures cluster logging is configured
  • eks-endpoint-private-access-enable: Validates private endpoint access

All rules include CIS compliance mappings and remediation guidance.

Testing Performed

Tested against multiple AWS accounts containing:

  • ECS clusters with Fargate and EC2 launch types
  • ECS services using capacity provider strategies
  • ECR repositories with various configurations
  • EKS clusters with different logging/networking setups
  • Large snapshot sets (validating rate limit handling)

Verified:

  • ✅ All container services scan successfully
  • ✅ Proper error handling for AWS rate limiting
  • ✅ Correct handling of optional fields across deployment types
  • ✅ No breaking changes to existing service scans
  • ✅ Rules trigger appropriately for misconfigured resources

Files Changed

New Files (Facades)

  • ScoutSuite/providers/aws/facade/ecr.py
  • ScoutSuite/providers/aws/facade/ecs.py
  • ScoutSuite/providers/aws/facade/eks.py

New Files (Resources)

  • ScoutSuite/providers/aws/resources/ecr/ (base.py, images.py, repositories.py)
  • ScoutSuite/providers/aws/resources/ecs/ (base.py, clusters.py, services.py, tasks.py)
  • ScoutSuite/providers/aws/resources/eks/ (base.py, clusters.py, nodegroups.py)

New Files (Rules)

  • ScoutSuite/providers/aws/rules/findings/ecr-image-scanning-enabled.json
  • ScoutSuite/providers/aws/rules/findings/ecr-tag-immutablity-enabled.json
  • ScoutSuite/providers/aws/rules/findings/ecs-container-insights-enabled.json
  • ScoutSuite/providers/aws/rules/findings/eks-cluster-logging-enabled.json
  • ScoutSuite/providers/aws/rules/findings/eks-endpoint-private-access-enable.json

New Files (HTML Templates)

  • ScoutSuite/output/data/html/partials/aws/services.ecr.regions.id.images.html
  • ScoutSuite/output/data/html/partials/aws/services.ecr.regions.id.repositories.html
  • ScoutSuite/output/data/html/partials/aws/services.ecs.regions.html
  • ScoutSuite/output/data/html/partials/aws/services.ecs.regions.id.clusters.html
  • ScoutSuite/output/data/html/partials/aws/services.ecs.regions.id.services.html
  • ScoutSuite/output/data/html/partials/aws/services.ecs.regions.id.tasks.html
  • ScoutSuite/output/data/html/partials/aws/services.eks.regions.id.clusters.html
  • ScoutSuite/output/data/html/partials/aws/services.eks.regions.id.nodegroups.html

Modified Files

  • ScoutSuite/providers/aws/facade/base.py (added container service facades)
  • ScoutSuite/providers/aws/facade/rds.py (bug fixes only)
  • ScoutSuite/providers/aws/services.py (added container service initialization)
  • ScoutSuite/providers/aws/metadata.json (added service metadata)
  • ScoutSuite/providers/aws/rules/rulesets/default.json (registered new rules)

Compatibility & Breaking Changes

  • ✅ No breaking changes to existing functionality
  • ✅ All existing services continue to work identically
  • ✅ New services are included in default scans automatically
  • ✅ Can be excluded with --skip ecs ecr eks if needed
  • ✅ RDS bug fixes improve robustness for all users

Known Behavior

Under high API load, AWS may rate-limit RDS snapshot attribute fetching. This is handled gracefully with warning-level logging. Snapshots are still discovered and included in resource counts; only detailed attributes may be incomplete. This affects <1% of resources in typical scenarios.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works (optional)
  • New and existing unit tests pass locally with my changes

Acknowledgments

kedarbhalerao1704 and others added 6 commits November 14, 2025 09:46
- Remove duplicate service initialization in services.py (lines 136-145)
  ECR, ECS, EKS were being initialized twice, causing conflicts

- Fix ECR facade async/await issues in ecr.py:
  * Added missing await in get_images() method (line 42)
  * Rewrote _get_image() to properly handle async operations
  * Fixed inefficient loop that was fetching ALL repositories for each image

- Fix ECS cluster parsing in clusters.py:
  * Added proper handling for missing containerInsights setting
  * Added default value to prevent KeyError
  * Added safety checks with .get() methods

- Fix facade initialization in base.py:
  * Moved ECR/ECS/EKS to standard service initialization
  * Removed from proprietary services section since they're now open-source

These fixes address critical bugs that would cause runtime errors
and performance issues in production environments.
Fixed critical bugs in ECS facade that caused API errors:

1. Service ARN parsing (_get_service):
   - Was incorrectly listing ALL clusters and concatenating ARNs
   - Now properly extracts cluster name from service ARN
   - Format: arn:aws:ecs:region:account:service/cluster-name/service-name

2. Task ARN parsing (_get_tasks):
   - Same issue as services - was concatenating all cluster ARNs
   - Now properly extracts cluster name from task ARN
   - Format: arn:aws:ecs:region:account:task/cluster-name/task-id

3. Missing await statements:
   - Added await to get_services() list_services call
   - Added await to get_tasks() list_tasks call
   - Added await to _get_service() describe_services call
   - Added await to _get_tasks() describe_tasks call

These fixes resolve the "Unsupported resource type: cluster" errors
that occurred when scanning accounts with ECS services and tasks.

Tested with AWS account containing multiple ECS clusters, services,
and tasks. All resources now scan successfully.
Fixed critical bugs where code assumed all fields exist in API responses:

1. ECS Tasks (tasks.py):
   - containerInstanceArn: Only exists for EC2 launch type, not Fargate
   - All fields now use .get() with sensible defaults
   - Added safe container parsing with existence checks

2. ECS Services (services.py):
   - launchType: Optional when using capacity provider strategies
   - All fields now use .get() with sensible defaults
   - Added safe deployment parsing with existence checks

These fixes handle the different ECS deployment models:
- Fargate vs EC2 launch types
- Capacity provider strategies vs direct launch types
- Services with/without active deployments
- Tasks with/without containers

Resolves KeyError: 'containerInstanceArn' and KeyError: 'launchType'
errors when scanning ECS resources.
Fixed critical bugs in RDS snapshot attribute fetching that caused
132 RDS snapshots to fail and not be counted as resources.

Issues fixed:
1. TypeError: "argument of type 'ClientError' is not iterable"
   - Line 119: Was checking if string 'in' ClientError object
   - Fixed: Convert exception to string first with str(e)

2. Improved throttling error handling:
   - AWS rate limits are hit when scanning many snapshots
   - Now properly detects and handles throttling gracefully
   - Uses print_warning for rate limits instead of print_exception

3. Applied same fixes to cluster snapshot attributes function

Root cause analysis:
- The official version scans faster (no ECS/ECR) so hits rate limits less
- Our fork scans ECS/ECR first, using API quota, then RDS hits limits
- The TypeError prevented proper error handling, causing silent failures
- Snapshots without 'Attributes' key couldn't be parsed, reducing resource count

This should restore the full 486 RDS resources in scan results.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Container Support AWS

2 participants