Skip to main content

ECS Task Definitions Using Host Networking Mode Run as Non-Root Users

Overview

This check ensures that Amazon ECS task definitions configured with host network mode run containers as non-root users. When containers share the host's network namespace, running as root significantly increases the security risk.

Risk

Running containers as root with host networking grants full access to the host's network stack. This can enable:

  • Privilege escalation - Root users can bind to low ports and sniff network traffic
  • Service impersonation - Attackers can pose as legitimate services
  • Kernel exploit amplification - Root access increases the severity of any kernel vulnerabilities
  • Data exfiltration - Unrestricted network access makes it easier to steal data

This is a high severity finding because it impacts confidentiality, integrity, and availability.

Remediation Steps

Prerequisites

You need permission to view and modify ECS task definitions. Specifically:

  • ecs:DescribeTaskDefinition
  • ecs:RegisterTaskDefinition

The best solution is to avoid host network mode entirely. Use awsvpc mode instead, which provides network isolation for each task.

In the AWS Console:

  1. Open the Amazon ECS console
  2. Click Task definitions in the left sidebar
  3. Select the task definition you need to update
  4. Click Create new revision
  5. Under Infrastructure requirements, change Network mode from host to awsvpc
  6. Click Create to save the new revision
  7. Update any services using this task definition to use the new revision

If Host Network Mode Is Required

If you must use host network mode (for example, for network monitoring tools), configure containers to run as a non-root user.

In the AWS Console:

  1. Open the Amazon ECS console
  2. Click Task definitions in the left sidebar
  3. Select the task definition you need to update
  4. Click Create new revision
  5. Scroll to the Container definitions section
  6. Click on the container name to expand its settings
  7. Under Environment, find the User field
  8. Enter a non-root user ID, such as 1000:1000 (user ID and group ID)
  9. Click Create to save the new revision
  10. Update any services using this task definition to use the new revision
AWS CLI Method

List task definitions to find those using host network mode:

aws ecs list-task-definitions \
--region us-east-1 \
--status ACTIVE

Inspect a specific task definition:

aws ecs describe-task-definition \
--task-definition <your-task-definition-name> \
--region us-east-1 \
--query 'taskDefinition.{NetworkMode:networkMode,Containers:containerDefinitions[*].{Name:name,User:user}}'

Register a new task definition with non-root user:

Create a file called task-definition.json:

{
"family": "my-secure-task",
"networkMode": "host",
"requiresCompatibilities": ["EC2"],
"containerDefinitions": [
{
"name": "my-container",
"image": "nginx:latest",
"essential": true,
"user": "1000:1000",
"memory": 512,
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080,
"protocol": "tcp"
}
],
"linuxParameters": {
"capabilities": {
"drop": ["ALL"]
}
}
}
]
}

Register the task definition:

aws ecs register-task-definition \
--cli-input-json file://task-definition.json \
--region us-east-1
CloudFormation Template

Option 1: Host network mode with non-root user (if host mode is required)

AWSTemplateFormatVersion: '2010-09-09'
Description: ECS Task Definition with host networking and non-root user

Parameters:
TaskDefinitionFamily:
Type: String
Default: my-secure-task
Description: Name for the task definition family

Resources:
ECSTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref TaskDefinitionFamily
NetworkMode: host
RequiresCompatibilities:
- EC2
ContainerDefinitions:
- Name: my-container
Image: nginx:latest
Essential: true
User: "1000:1000"
PortMappings:
- ContainerPort: 8080
HostPort: 8080
Protocol: tcp
LinuxParameters:
Capabilities:
Drop:
- ALL
Memory: 512

Outputs:
TaskDefinitionArn:
Description: ARN of the task definition
Value: !Ref ECSTaskDefinition

Option 2: awsvpc network mode (recommended)

AWSTemplateFormatVersion: '2010-09-09'
Description: ECS Task Definition with awsvpc networking (recommended)

Parameters:
TaskDefinitionFamily:
Type: String
Default: my-secure-task
Description: Name for the task definition family
ExecutionRoleArn:
Type: String
Description: ARN of the ECS task execution role

Resources:
ECSTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref TaskDefinitionFamily
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: '256'
Memory: '512'
ExecutionRoleArn: !Ref ExecutionRoleArn
ContainerDefinitions:
- Name: my-container
Image: nginx:latest
Essential: true
PortMappings:
- ContainerPort: 80
Protocol: tcp

Outputs:
TaskDefinitionArn:
Description: ARN of the task definition
Value: !Ref ECSTaskDefinition
Terraform Configuration

Option 1: Host network mode with non-root user (if host mode is required)

resource "aws_ecs_task_definition" "secure_host_mode" {
family = "my-secure-task"
network_mode = "host"

requires_compatibilities = ["EC2"]

container_definitions = jsonencode([
{
name = "my-container"
image = "nginx:latest"
essential = true
user = "1000:1000"
memory = 512

portMappings = [
{
containerPort = 8080
hostPort = 8080
protocol = "tcp"
}
]

linuxParameters = {
capabilities = {
drop = ["ALL"]
}
}
}
])
}

Option 2: awsvpc network mode (recommended)

resource "aws_ecs_task_definition" "secure_awsvpc_mode" {
family = "my-secure-task"
network_mode = "awsvpc"

requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = var.execution_role_arn

container_definitions = jsonencode([
{
name = "my-container"
image = "nginx:latest"
essential = true

portMappings = [
{
containerPort = 80
protocol = "tcp"
}
]
}
])
}

variable "execution_role_arn" {
description = "ARN of the ECS task execution role"
type = string
}

Verification

After updating your task definition:

  1. Open the Amazon ECS console
  2. Click Task definitions and select your updated task definition
  3. Click the latest revision
  4. Check that either:
    • The Network mode is awsvpc (preferred), or
    • Each container has a User value set to a non-root user (not root or empty)
CLI Verification

Verify the task definition configuration:

aws ecs describe-task-definition \
--task-definition <your-task-definition-name> \
--region us-east-1 \
--query 'taskDefinition.{NetworkMode:networkMode,Containers:containerDefinitions[*].{Name:name,User:user,Privileged:privileged}}'

Run Prowler to confirm the check passes:

prowler aws --checks ecs_task_definitions_host_networking_mode_users

Additional Resources

Notes

  • Container image compatibility: Some container images are designed to run as root. You may need to rebuild your container image to support running as a non-root user.
  • Port binding: Non-root users cannot bind to ports below 1024. Configure your container to use higher ports (e.g., 8080 instead of 80).
  • File permissions: Ensure the container user has read/write access to any required files and directories.
  • Service updates: After registering a new task definition revision, you must update your ECS services to use the new revision for changes to take effect.
  • Fargate considerations: Fargate tasks always use awsvpc network mode and run as the user specified in the task definition or container image.