Lambda Function Without Tags

  • Query id: 8df8e857-bd59-44fa-9f4c-d77594b95b46
  • Query name: Lambda Function Without Tags
  • Platform: CloudFormation
  • Severity: Medium
  • Category: Insecure Configurations
  • URL: Github

Description

AWS Lambda Functions must have associated tags.
Documentation

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - yaml file
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  ExistingSecurityGroups:
    Type: List<AWS::EC2::SecurityGroup::Id>
  ExistingVPC:
    Type: AWS::EC2::VPC::Id
    Description: The VPC ID that includes the security groups in the ExistingSecurityGroups
      parameter.
  InstanceType:
    Type: String
    Default: t2.micro
    AllowedValues:
    - t2.micro
    - m1.small
Mappings:
  AWSInstanceType2Arch:
    t2.micro:
      Arch: HVM64
    m1.small:
      Arch: HVM64
  AWSRegionArch2AMI:
    us-east-1:
      HVM64: ami-0ff8a91507f77f867
      HVMG2: ami-0a584ac55a7631c0c
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP traffic to the host
      VpcId:
        Ref: ExistingVPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '80'
        ToPort: '80'
        CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: '80'
        ToPort: '80'
        CidrIp: 0.0.0.0/0
  AllSecurityGroups:
    Type: Custom::Split
    Properties:
      ServiceToken: !GetAtt AppendItemToListFunction.Arn
      List:
        Ref: ExistingSecurityGroups
      AppendedItem:
        Ref: SecurityGroup
  AppendItemToListFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: !Sub |
          var response = require('cfn-response');
          exports.handler = function(event, context) {
             var responseData = {Value: event.ResourceProperties.List};
             responseData.Value.push(event.ResourceProperties.AppendedItem);
             response.send(event, context, response.SUCCESS, responseData);
          };
      Runtime: nodejs8.10
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId:
        Fn::FindInMap:
        - AWSRegionArch2AMI
        - Ref: AWS::Region
        - Fn::FindInMap:
          - AWSInstanceType2Arch
          - Ref: InstanceType
          - Arch
      SecurityGroupIds: !GetAtt AllSecurityGroups.Value
      InstanceType:
        Ref: InstanceType
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: root
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:*
            Resource: arn:aws:logs:*:*:*
Outputs:
  AllSecurityGroups:
    Description: Security Groups that are associated with the EC2 instance
    Value:
      Fn::Join:
      - ", "
      - Fn::GetAtt:
        - AllSecurityGroups
        - Value
Positive test num. 2 - json file
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "ExistingVPC": {
      "Type": "AWS::EC2::VPC::Id",
      "Description": "The VPC ID that includes the security groups in the ExistingSecurityGroups parameter."
    },
    "InstanceType": {
      "Type": "String",
      "Default": "t2.micro",
      "AllowedValues": [
        "t2.micro",
        "m1.small"
      ]
    },
    "ExistingSecurityGroups": {
      "Type": "List\u003cAWS::EC2::SecurityGroup::Id\u003e"
    }
  },
  "Mappings": {
    "AWSInstanceType2Arch": {
      "t2.micro": {
        "Arch": "HVM64"
      },
      "m1.small": {
        "Arch": "HVM64"
      }
    },
    "AWSRegionArch2AMI": {
      "us-east-1": {
        "HVM64": "ami-0ff8a91507f77f867",
        "HVMG2": "ami-0a584ac55a7631c0c"
      }
    }
  },
  "Resources": {
    "SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Allow HTTP traffic to the host",
        "VpcId": {
          "Ref": "ExistingVPC"
        },
        "SecurityGroupIngress": [
          {
            "FromPort": "80",
            "ToPort": "80",
            "CidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "tcp",
            "FromPort": "80",
            "ToPort": "80",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "AllSecurityGroups": {
      "Type": "Custom::Split",
      "Properties": {
        "ServiceToken": "AppendItemToListFunction.Arn",
        "List": {
          "Ref": "ExistingSecurityGroups"
        },
        "AppendedItem": {
          "Ref": "SecurityGroup"
        }
      }
    },
    "AppendItemToListFunction": {
      "Properties": {
        "Handler": "index.handler",
        "Role": "LambdaExecutionRole.Arn",
        "Code": {
          "ZipFile": "var response = require('cfn-response');\nexports.handler = function(event, context) {\n   var responseData = {Value: event.ResourceProperties.List};\n   responseData.Value.push(event.ResourceProperties.AppendedItem);\n   response.send(event, context, response.SUCCESS, responseData);\n};\n"
        },
        "Runtime": "nodejs8.10"
      },
      "Type": "AWS::Lambda::Function"
    },
    "MyEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": {
          "Fn::FindInMap": [
            "AWSRegionArch2AMI",
            {
              "Ref": "AWS::Region"
            },
            {
              "Fn::FindInMap": [
                "AWSInstanceType2Arch",
                {
                  "Ref": "InstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "SecurityGroupIds": "AllSecurityGroups.Value",
        "InstanceType": {
          "Ref": "InstanceType"
        }
      }
    },
    "LambdaExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "Policies": [
          {
            "PolicyName": "root",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Action": [
                    "logs:*"
                  ],
                  "Resource": "arn:aws:logs:*:*:*"
                }
              ]
            }
          }
        ],
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": [
                "sts:AssumeRole"
              ],
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "lambda.amazonaws.com"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "Path": "/"
      }
    }
  },
  "Outputs": {
    "AllSecurityGroups": {
      "Description": "Security Groups that are associated with the EC2 instance",
      "Value": {
        "Fn::Join": [
          ", ",
          {
            "Fn::GetAtt": [
              "AllSecurityGroups",
              "Value"
            ]
          }
        ]
      }
    }
  }
}

Code samples without security vulnerabilities

Negative test num. 1 - yaml file
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC function.
Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Role: arn:aws:iam::123456789012:role/lambda-role
      Code:
        S3Bucket: my-bucket
        S3Key: function.zip
      Runtime: nodejs12.x
      Timeout: 5
      TracingConfig:
        Mode: Active
      VpcConfig:
        SecurityGroupIds:
          - sg-085912345678492fb
        SubnetIds:
          - subnet-071f712345678e7c8
          - subnet-07fd123456788a036
      Tags:
        - Key: Description
          Value: VPC Function
        - Key: Type
          Value: AWS Lambda Function
Negative test num. 2 - json file
{
  "Description": "VPC function.",
  "Resources": {
    "Function": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Runtime": "nodejs12.x",
        "Timeout": 5,
        "TracingConfig": {
          "Mode": "Active"
        },
        "VpcConfig": {
          "SecurityGroupIds": [
            "sg-085912345678492fb"
          ],
          "SubnetIds": [
            "subnet-071f712345678e7c8",
            "subnet-07fd123456788a036"
          ]
        },
        "Tags": [
          {
            "Value": "VPC Function",
            "Key": "Description"
          },
          {
            "Key": "Type",
            "Value": "AWS Lambda Function"
          }
        ],
        "Handler": "index.handler",
        "Role": "arn:aws:iam::123456789012:role/lambda-role",
        "Code": {
          "S3Bucket": "my-bucket",
          "S3Key": "function.zip"
        }
      }
    }
  },
  "AWSTemplateFormatVersion": "2010-09-09"
}