Empty Roles For ECS Cluster Task Definitions

  • Query id: 7f384a5f-b5a2-4d84-8ca3-ee0a5247becb
  • Query name: Empty Roles For ECS Cluster Task Definitions
  • Platform: CloudFormation
  • Severity: Medium
  • Category: Access Control
  • URL: Github

Description

Check if any ECS cluster has not defined proper roles for services' task definitions.
Documentation

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - yaml file
Resources:
  NoTaskDefinition:
    Type: AWS::ECS::Service
    DependsOn:
    - Listener
    Properties:
      Role:
        Ref: ECSServiceRole
      DesiredCount: 1
      LoadBalancers:
      - TargetGroupArn:
          Ref: TargetGroup
        ContainerPort: 80
        ContainerName: sample-app
      Cluster:
        Ref: ECSCluster
  InvalidTaskDefinition:
    Type: AWS::ECS::Service
    DependsOn:
    - Listener
    Properties:
      Role:
        Ref: ECSServiceRole
      TaskDefinition:
        Ref: MissingTaskDefinition
      DesiredCount: 1
      LoadBalancers:
      - TargetGroupArn:
          Ref: TargetGroup
        ContainerPort: 80
        ContainerName: sample-app
      Cluster:
        Ref: ECSCluster
  TaskNoRole:
    Type: AWS::ECS::Service
    DependsOn:
    - Listener
    Properties:
      Role:
        Ref: ECSServiceRole
      TaskDefinition:
        Ref: ECSTaskDefinition
      DesiredCount: 1
      LoadBalancers:
      - TargetGroupArn:
          Ref: TargetGroup
        ContainerPort: 80
        ContainerName: sample-app
      Cluster:
        Ref: ECSCluster
  ECSTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Ref 'ServiceName'
      Cpu: !Ref 'ContainerCpu'
      Memory: !Ref 'ContainerMemory'
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn:
        Fn::ImportValue:
          !Join [':', [!Ref 'StackName', 'ECSTaskExecutionRole']]
      ContainerDefinitions:
        - Name: !Ref 'ServiceName'
          Cpu: !Ref 'ContainerCpu'
          Memory: !Ref 'ContainerMemory'
          Image: !Ref 'ImageUrl'
          PortMappings:
            - ContainerPort: !Ref 'ContainerPort'
Positive test num. 2 - json file
{
  "Resources": {
    "InvalidTaskDefinition": {
      "DependsOn": [
        "Listener"
      ],
      "Properties": {
        "Role": {
          "Ref": "ECSServiceRole"
        },
        "TaskDefinition": {
          "Ref": "MissingTaskDefinition"
        },
        "DesiredCount": 1,
        "LoadBalancers": [
          {
            "TargetGroupArn": {
              "Ref": "TargetGroup"
            },
            "ContainerPort": 80,
            "ContainerName": "sample-app"
          }
        ],
        "Cluster": {
          "Ref": "ECSCluster"
        }
      },
      "Type": "AWS::ECS::Service"
    },
    "TaskNoRole": {
      "Type": "AWS::ECS::Service",
      "DependsOn": [
        "Listener"
      ],
      "Properties": {
        "Role": {
          "Ref": "ECSServiceRole"
        },
        "TaskDefinition": {
          "Ref": "ECSTaskDefinition"
        },
        "DesiredCount": 1,
        "LoadBalancers": [
          {
            "ContainerPort": 80,
            "ContainerName": "sample-app",
            "TargetGroupArn": {
              "Ref": "TargetGroup"
            }
          }
        ],
        "Cluster": {
          "Ref": "ECSCluster"
        }
      }
    },
    "ECSTaskDefinition": {
      "Type": "AWS::ECS::TaskDefinition",
      "Properties": {
        "ContainerDefinitions": [
          {
            "Image": "ImageUrl",
            "PortMappings": [
              {
                "ContainerPort": "ContainerPort"
              }
            ],
            "Name": "ServiceName",
            "Cpu": "ContainerCpu",
            "Memory": "ContainerMemory"
          }
        ],
        "Family": "ServiceName",
        "Cpu": "ContainerCpu",
        "Memory": "ContainerMemory",
        "NetworkMode": "awsvpc",
        "RequiresCompatibilities": [
          "FARGATE"
        ],
        "ExecutionRoleArn": {
          "Fn::ImportValue": [
            ":",
            [
              "StackName",
              "ECSTaskExecutionRole"
            ]
          ]
        }
      }
    },
    "NoTaskDefinition": {
      "Type": "AWS::ECS::Service",
      "DependsOn": [
        "Listener"
      ],
      "Properties": {
        "Role": {
          "Ref": "ECSServiceRole"
        },
        "DesiredCount": 1,
        "LoadBalancers": [
          {
            "TargetGroupArn": {
              "Ref": "TargetGroup"
            },
            "ContainerPort": 80,
            "ContainerName": "sample-app"
          }
        ],
        "Cluster": {
          "Ref": "ECSCluster"
        }
      }
    }
  }
}

Code samples without security vulnerabilities

Negative test num. 1 - yaml file
Resources:
  ECSService:
    Type: AWS::ECS::Service
    DependsOn:
    - Listener
    Properties:
      Role:
        Ref: ECSServiceRole
      TaskDefinition:
        Ref: ECSTaskDefinition
      DesiredCount: 1
      LoadBalancers:
      - TargetGroupArn:
          Ref: TargetGroup
        ContainerPort: 80
        ContainerName: sample-app
      Cluster:
        Ref: ECSCluster
  ECSTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Ref 'ServiceName'
      Cpu: !Ref 'ContainerCpu'
      Memory: !Ref 'ContainerMemory'
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn:
        Fn::ImportValue:
          !Join [':', [!Ref 'StackName', 'ECSTaskExecutionRole']]
      TaskRoleArn:
        Fn::If:
          - 'HasCustomRole'
          - !Ref 'Role'
          - !Ref "AWS::NoValue"
      ContainerDefinitions:
        - Name: !Ref 'ServiceName'
          Cpu: !Ref 'ContainerCpu'
          Memory: !Ref 'ContainerMemory'
          Image: !Ref 'ImageUrl'
          PortMappings:
            - ContainerPort: !Ref 'ContainerPort'
Negative test num. 2 - json file
{
  "Resources": {
    "ECSTaskDefinition": {
      "Properties": {
        "Memory": "ContainerMemory",
        "NetworkMode": "awsvpc",
        "RequiresCompatibilities": [
          "FARGATE"
        ],
        "ExecutionRoleArn": {
          "Fn::ImportValue": [
            ":",
            [
              "StackName",
              "ECSTaskExecutionRole"
            ]
          ]
        },
        "TaskRoleArn": {
          "Fn::If": [
            "HasCustomRole",
            "Role",
            "AWS::NoValue"
          ]
        },
        "ContainerDefinitions": [
          {
            "Name": "ServiceName",
            "Cpu": "ContainerCpu",
            "Memory": "ContainerMemory",
            "Image": "ImageUrl",
            "PortMappings": [
              {
                "ContainerPort": "ContainerPort"
              }
            ]
          }
        ],
        "Family": "ServiceName",
        "Cpu": "ContainerCpu"
      },
      "Type": "AWS::ECS::TaskDefinition"
    },
    "ECSService": {
      "Type": "AWS::ECS::Service",
      "DependsOn": [
        "Listener"
      ],
      "Properties": {
        "DesiredCount": 1,
        "LoadBalancers": [
          {
            "TargetGroupArn": {
              "Ref": "TargetGroup"
            },
            "ContainerPort": 80,
            "ContainerName": "sample-app"
          }
        ],
        "Cluster": {
          "Ref": "ECSCluster"
        },
        "Role": {
          "Ref": "ECSServiceRole"
        },
        "TaskDefinition": {
          "Ref": "ECSTaskDefinition"
        }
      }
    }
  }
}