AWS Lambda controles - AWS Control Tower

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

AWS Lambda controles

[CT.LAMBDA.PR.2] Exigir políticas de AWS Lambda funções para proibir o acesso público

Esse controle verifica se uma política baseada em recursos de AWS Lambda função proíbe o acesso público.

  • Objetivo do controle: limitar o acesso à rede

  • Implementação: regra de AWS CloudFormation guarda

  • Comportamento de controle: proativo

  • Tipos de recursos: AWS::Lambda::Permission

  • AWS CloudFormation regra de guarda: CT.LAMBDA.PR.2especificação da regra

Detalhes e exemplos

Explicação

A função Lambda não deve ser acessível ao público, pois pode permitir acesso não intencional ao seu código armazenado na função.

Remediação em caso de falha de regra

Ao Principal configurar*, forneça um dos SourceAccountSourceArn, ouPrincipalOrgID. Ao Principal configurar como principal de serviço (por exemplo, s3.amazonaws.com), forneça um dos ou. SourceAccount SourceArn

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda Política de funções - Exemplo 1

AWS Lambda política de função configurada com um Conta da AWS ID principal. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "LambdaPermission": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "LambdaFunction" }, "Principal": { "Ref": "AWS::AccountId" } } } }

Exemplo de YAML

LambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref 'LambdaFunction' Principal: !Ref 'AWS::AccountId'

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda Política de funções - Exemplo dois

AWS Lambda política de função configurada com um caractere curinga principal e condição de conta de origem. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "LambdaPermission": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "LambdaFunction" }, "Principal": "*", "SourceAccount": { "Ref": "AWS::AccountId" } } } }

Exemplo de YAML

LambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref 'LambdaFunction' Principal: '*' SourceAccount: !Ref 'AWS::AccountId'

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda Política de funções - Exemplo três

AWS Lambda política de função configurada com um principal de serviço e uma condição de ARN de origem. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "LambdaPermission": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "LambdaFunction" }, "Principal": "s3.amazonaws.com", "SourceArn": { "Fn::GetAtt": [ "S3Bucket", "Arn" ] } } } }

Exemplo de YAML

LambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref 'LambdaFunction' Principal: s3.amazonaws.com SourceArn: !GetAtt 'S3Bucket.Arn'

CT.LAMBDA.PR.2especificação da regra

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # lambda_function_public_access_prohibited_check # # Description: # This control checks whether an AWS Lambda function resource-based policy prohibits public access. # # Reports on: # AWS::Lambda::Permission # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Lambda permission resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda permission resource # And: 'FunctionUrlAuthType' has been provided with a value of 'NONE' # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda permission resource # And: 'Principal' has been provided with a wildcard value ('*') # And: 'SourceAccount' has not been provided or provided with an empty string value # And: 'SourceArn' has not been provided or provided with an empty string value or non-valid local reference # And: 'PrincipalOrgID' has not been provided or provided with an empty string value # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda permission resource # And: 'Principal' has been provided with value that does not match an AWS Account ID, AWS IAM ARN or # wildcard value ('*') # And: 'SourceAccount' has not been provided or provided with an empty string value # And: 'SourceArn' has not been provided or provided with an empty string value or non-valid local reference # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda permission resource # And: 'Principal' has been provided with an AWS Account ID or AWS IAM ARN value # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda permission resource # And: 'Principal' has been provided with a wildcard value ('*') # And: At least one of 'SourceAccount', 'SourceArn' or 'PrincipalOrgID' have been provided with non-empty string # values (or a valid local reference for 'SourceArn') # Then: PASS # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda permission resource # And: 'Principal' has been provided with value that does not match an AWS Account ID or AWS IAM ARN # And: At least one of 'SourceAccount', 'SourceArn' have been provided with non-empty string values (or a valid # local reference for 'SourceArn') # Then: PASS # # Constants # let LAMBDA_PERMISSION_TYPE = "AWS::Lambda::Permission" let AWS_ACCOUNT_ID_PATTERN = /\d{12}/ let AWS_IAM_PRINCIPAL_PATTERN = /^arn:aws[a-z0-9\-]*:iam::\d{12}:.+/ let INPUT_DOCUMENT = this # # Assignments # let lambda_permissions = Resources.*[ Type == %LAMBDA_PERMISSION_TYPE ] # # Primary Rules # rule lambda_function_public_access_prohibited_check when is_cfn_template(%INPUT_DOCUMENT) %lambda_permissions not empty { check(%lambda_permissions.Properties) << [CT.LAMBDA.PR.2]: Require AWS Lambda function policies to prohibit public access [FIX]: When setting 'Principal' to '*', provide one of 'SourceAccount', 'SourceArn', or 'PrincipalOrgID'. When setting 'Principal' to a service principal (for example, s3.amazonaws.com), provide one of 'SourceAccount' or 'SourceArn'. >> } rule lambda_function_public_access_prohibited_check when is_cfn_hook(%INPUT_DOCUMENT, %LAMBDA_PERMISSION_TYPE) { check(%INPUT_DOCUMENT.%LAMBDA_PERMISSION_TYPE.resourceProperties) << [CT.LAMBDA.PR.2]: Require AWS Lambda function policies to prohibit public access [FIX]: When setting 'Principal' to '*', provide one of 'SourceAccount', 'SourceArn', or 'PrincipalOrgID'. When setting 'Principal' to a service principal (for example, s3.amazonaws.com), provide one of 'SourceAccount' or 'SourceArn'. >> } # # Parameterized Rules # rule check(lambda_permission) { %lambda_permission { # Scenario 2 and 5 FunctionUrlAuthType not exists or FunctionUrlAuthType != "NONE" } %lambda_permission [ Principal exists Principal == "*" ] { # Scenario 3 and 6 SourceAccount exists or SourceArn exists or PrincipalOrgID exists check_is_string_and_not_empty(SourceAccount) or check_is_string_or_local_reference(SourceArn) or check_is_string_and_not_empty(PrincipalOrgID) } %lambda_permission [ Principal exists Principal != "*" Principal != %AWS_ACCOUNT_ID_PATTERN Principal != %AWS_IAM_PRINCIPAL_PATTERN ] { # Scenario 4 and 7 SourceAccount exists or SourceArn exists check_is_string_and_not_empty(SourceAccount) or check_is_string_or_local_reference(SourceArn) } } rule check_is_string_or_local_reference(value) { %value { check_is_string_and_not_empty(this) or check_local_references(%INPUT_DOCUMENT, this) } } rule check_local_references(doc, reference_properties) { %reference_properties { 'Fn::GetAtt' { query_for_resource(%doc, this[0]) <<Local Stack reference was invalid>> } or Ref { query_for_resource(%doc, this) <<Local Stack reference was invalid>> } } } rule query_for_resource(doc, resource_key) { let referenced_resource = %doc.Resources[ keys == %resource_key ] %referenced_resource not empty } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_is_string_and_not_empty(value) { %value { this is_string this != /\A\s*\z/ } }

CT.LAMBDA.PR.2modelos de exemplo

Você pode ver exemplos dos artefatos de teste PASS e FAIL para os controles proativos do AWS Control Tower.

Exemplo de PASS - Use esse modelo para verificar a criação de um recurso compatível.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Runtime: python3.9 Code: ZipFile: "def handler(event, context):\n print(\"hello\")\n" Description: TestS3EventFunction LambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: Ref: LambdaFunction Principal: Ref: AWS::AccountId

Exemplo de FALHA - Use esse modelo para verificar se o controle impede a criação de recursos não compatíveis.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Runtime: python3.9 Code: ZipFile: "def handler(event, context):\n print(\"hello\")\n" Description: TestS3EventFunction LambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: Ref: LambdaFunction Principal: '*'

[CT.LAMBDA.PR.3] Exija que uma AWS Lambda função esteja em uma Amazon Virtual Private Cloud (VPC) gerenciada pelo cliente

Esse controle verifica se uma função do AWS Lambda foi configurada com acesso aos recursos em uma Amazon Virtual Private Cloud (VPC) gerenciada pelo cliente.

  • Objetivo do controle: limitar o acesso à rede

  • Implementação: regra de AWS CloudFormation guarda

  • Comportamento de controle: proativo

  • Tipos de recursos: AWS::Lambda::Function

  • AWS CloudFormation regra de guarda: Especificação da regra CT.LAMBDA.PR.3

Detalhes e exemplos

Explicação

AWS Lambda as funções podem ser vinculadas a sub-redes privadas em uma nuvem privada virtual (VPC) na sua Conta da AWS para se conectar a recursos como bancos de dados, instâncias de cache ou serviços internos. Certifique-se de que as sub-redes e os grupos de segurança usados permitam o acesso aos recursos necessários.

Considerações de uso
  • Esse controle não avalia a configuração de roteamento de sub-rede da VPC para determinar a acessibilidade pública.

  • Esse controle não é compatível com as funções do AWS Lambda @Edge. O Lambda @Edge não oferece suporte a funções configuradas com acesso a recursos dentro da sua VPC.

  • As funções do Lambda não podem se conectar diretamente a uma VPC com a locação de instâncias dedicadas. Para se conectar a recursos em uma VPC dedicada, emparelhe-a com uma segunda VPC com locação padrão.

Remediação em caso de falha de regra

EmVpcConfig, forneça à SubnetIds propriedade uma ou mais IDs de sub-rede e forneça à SecurityGroupIds propriedade uma ou mais IDs de grupo de segurança.

Os exemplos a seguir mostram como implementar essa remediação.

Função AWS Lambda — Exemplo

Função do AWS Lambda configurada para acessar recursos em uma VPC. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "LambdaFunction": { "Type": "AWS::Lambda::Function", "Properties": { "Role": { "Fn::GetAtt": "LambdaFunctionRole.Arn" }, "Handler": "index.handler", "Code": { "ZipFile": "def handler(event, context):\n print(\"sample function\")\n" }, "Runtime": "python3.9", "VpcConfig": { "SubnetIds": [ { "Fn::GetAtt": [ "SubnetOne", "SubnetId" ] }, { "Fn::GetAtt": [ "SubnetTwo", "SubnetId" ] } ], "SecurityGroupIds": [ { "Fn::GetAtt": [ "SecurityGroup", "GroupId" ] } ] } } } }

Exemplo de YAML

LambdaFunction: Type: AWS::Lambda::Function Properties: Role: !GetAtt 'LambdaFunctionRole.Arn' Handler: index.handler Code: ZipFile: "def handler(event, context):\n print(\"sample function\")\n" Runtime: python3.9 VpcConfig: SubnetIds: - !GetAtt 'SubnetOne.SubnetId' - !GetAtt 'SubnetTwo.SubnetId' SecurityGroupIds: - !GetAtt 'SecurityGroup.GroupId'

Especificação da regra CT.LAMBDA.PR.3

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # lambda_inside_vpc_check # # Description: # This control checks whether an AWS Lambda function has been configured with access to resources in a customer-managed Amazon Virtual Private Cloud (VPC). # # Reports on: # AWS::Lambda::Function # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Lambda function resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function resource # And: 'VpcConfig' has not been provided # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function resource # And: 'VpcConfig' has been provided # And: 'SubnetIds' in 'VpcConfig' has been provided as a non-empty list that contains non-empty strings or valid # local references # And: 'SecurityGroupIds' in 'VpcConfig' has not been been provided or has been provided as an empty list # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function resource # And: 'VpcConfig' has been provided # And: 'SecurityGroupIds' in 'VpcConfig' has been provided as a non-empty list that contains non-empty strings # or valid local references # And: 'SubnetIds' in 'VpcConfig' has not been been provided or has been provided as an empty list # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function resource # And: 'VpcConfig' has been provided # And: 'SecurityGroupIds' in 'VpcConfig' has been provided as a non-empty list that contains non-empty strings or # valid local references # And: 'SubnetIds' in 'VpcConfig' has been provided as a non-empty list that contains non-empty strings or valid # local references # Then: PASS # # Constants # let LAMBDA_FUNCTION_TYPE = "AWS::Lambda::Function" let INPUT_DOCUMENT = this # # Assignments # let lambda_functions = Resources.*[ Type == %LAMBDA_FUNCTION_TYPE ] # # Primary Rules # rule lambda_inside_vpc_check when is_cfn_template(%INPUT_DOCUMENT) %lambda_functions not empty { check(%lambda_functions.Properties) << [CT.LAMBDA.PR.3]: Require an AWS Lambda function to be in a customer-managed Amazon Virtual Private Cloud (VPC) [FIX]: In 'VpcConfig', provide the 'SubnetIds' property with one or more Subnet IDs, and provide the 'SecurityGroupIds' property with one or more Security Group IDs. >> } rule lambda_inside_vpc_check when is_cfn_hook(%INPUT_DOCUMENT, %LAMBDA_FUNCTION_TYPE) { check(%INPUT_DOCUMENT.%LAMBDA_FUNCTION_TYPE.resourceProperties) << [CT.LAMBDA.PR.3]: Require an AWS Lambda function to be in a customer-managed Amazon Virtual Private Cloud (VPC) [FIX]: In 'VpcConfig', provide the 'SubnetIds' property with one or more Subnet IDs, and provide the 'SecurityGroupIds' property with one or more Security Group IDs. >> } # # Parameterized Rules # rule check(lambda_function) { %lambda_function { # Scenario 2 VpcConfig exists VpcConfig is_struct VpcConfig { # Scenario 3 and 5 SubnetIds exists SubnetIds is_list SubnetIds not empty SubnetIds[*] { check_is_string_and_not_empty(this) or check_local_references(%INPUT_DOCUMENT, this, "AWS::EC2::Subnet") } # Scenario 4 and 5 SecurityGroupIds exists SecurityGroupIds is_list SecurityGroupIds not empty SecurityGroupIds[*] { check_is_string_and_not_empty(this) or check_local_references(%INPUT_DOCUMENT, this, "AWS::EC2::SecurityGroup") } } } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_is_string_and_not_empty(value) { %value { this is_string this != /\A\s*\z/ } } rule check_local_references(doc, reference_properties, referenced_resource_type) { %reference_properties { 'Fn::GetAtt' { query_for_resource(%doc, this[0], %referenced_resource_type) <<Local Stack reference was invalid>> } or Ref { query_for_resource(%doc, this, %referenced_resource_type) <<Local Stack reference was invalid>> } } } rule query_for_resource(doc, resource_key, referenced_resource_type) { let referenced_resource = %doc.Resources[ keys == %resource_key ] %referenced_resource not empty %referenced_resource { Type == %referenced_resource_type } }

Modelos de exemplo do CT.LAMBDA.PR.3

Você pode ver exemplos dos artefatos de teste PASS e FAIL para os controles proativos do AWS Control Tower.

Exemplo de PASS - Use esse modelo para verificar a criação de um recurso compatível.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: 'true' EnableDnsHostnames: 'true' SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/24 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' SecurityGroup1: Type: AWS::EC2::SecurityGroup Properties: VpcId: Ref: VPC GroupDescription: Fn::Sub: ${AWS::StackName}-example LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - ec2:CreateNetworkInterface - ec2:DescribeNetworkInterfaces - ec2:DeleteNetworkInterface Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Code: ZipFile: | def handler(event, context): print("example") Runtime: python3.9 VpcConfig: SubnetIds: - Fn::GetAtt: - SubnetOne - SubnetId - Fn::GetAtt: - SubnetTwo - SubnetId SecurityGroupIds: - Fn::GetAtt: - SecurityGroup1 - GroupId

Exemplo de FALHA - Use esse modelo para verificar se o controle impede a criação de recursos não compatíveis.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - ec2:CreateNetworkInterface - ec2:DescribeNetworkInterfaces - ec2:DeleteNetworkInterface Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Code: ZipFile: | def handler(event, context): print("example") Runtime: python3.9

[CT.LAMBDA.PR.4] Exigir uma permissão de AWS Lambda camada para conceder acesso a uma AWS organização ou específica Conta da AWS

Esse controle verifica se uma permissão de AWS Lambda camada foi configurada para conceder acesso a uma AWS organização ou Conta da AWS somente a uma específica, garantindo que o acesso público de todos não Contas da AWS tenha sido concedido a uma camada.

  • Objetivo de controle: impor o menor privilégio

  • Implementação: regra de AWS CloudFormation guarda

  • Comportamento de controle: proativo

  • Tipos de recursos: AWS::Lambda::LayerVersionPermission

  • AWS CloudFormation regra de guarda: Especificação da regra CT.LAMBDA.PR.4

Detalhes e exemplos

Explicação

Por padrão, uma camada que você cria é privada para você Conta da AWS. No entanto, você pode compartilhar a camada com outras contas ou torná-la pública, opcionalmente.

Uma camada pública pode permitir acesso não intencional ao seu código-fonte e aplicativos. Uma camada pública do Lambda pode expor informações valiosas sobre sua conta, recursos e processos internos.

Remediação em caso de falha de regra

Defina o OrganizationId parâmetro como a ID de uma AWS organização ou defina o Principal parâmetro como uma Conta da AWS ID.

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda permissão de camada - Exemplo um

Uma URL de permissão de AWS Lambda versão configurada para conceder permissão de uso da camada para todas as contas em uma organização. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "LayerVersionPermission": { "Type": "AWS::Lambda::LayerVersionPermission", "Properties": { "Action": "lambda:GetLayerVersion", "LayerVersionArn": { "Ref": "LayerVersion" }, "OrganizationId": "o-abc123defg" } } }

Exemplo de YAML

LayerVersionPermission: Type: AWS::Lambda::LayerVersionPermission Properties: Action: lambda:GetLayerVersion LayerVersionArn: !Ref 'LayerVersion' OrganizationId: o-abc123defg

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda permissão de camada - Exemplo dois

Uma URL de permissão de AWS Lambda versão configurada para conceder permissão de uso da camada para um Conta da AWS. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "LayerVersionPermission": { "Type": "AWS::Lambda::LayerVersionPermission", "Properties": { "Action": "lambda:GetLayerVersion", "LayerVersionArn": { "Ref": "LayerVersion" }, "Principal": "123456789012" } } }

Exemplo de YAML

LayerVersionPermission: Type: AWS::Lambda::LayerVersionPermission Properties: Action: lambda:GetLayerVersion LayerVersionArn: !Ref 'LayerVersion' Principal: '123456789012'

Especificação da regra CT.LAMBDA.PR.4

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # lambda_layer_public_access_prohibited_check # # Description: # This control checks whether an AWS Lambda layer permission has been configured to grant access to an AWS organization or to a specific Conta da AWS only, by ensuring that public access from all Contas da AWS has not been granted to a layer. # # Reports on: # AWS::Lambda::LayerVersionPermission # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Lambda layer version permission resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda layer version permission resource # And: 'OrganizationId' has not been provided # And: 'Principal' has been provided and set to '*' # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda layer version permission resource # And: 'OrganizationId' has not been provided # And: 'Principal' has been provided and set to a non-empty string value other than '*' # Then: PASS # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda layer version permission resource # And: 'OrganizationId' has been provided as a non-empty string # Then: PASS # # Constants # let LAMBDA_LAYER_PERMISSION_TYPE = "AWS::Lambda::LayerVersionPermission" let INPUT_DOCUMENT = this # # Assignments # let lambda_layer_permissions = Resources.*[ Type == %LAMBDA_LAYER_PERMISSION_TYPE ] # # Primary Rules # rule lambda_layer_public_access_prohibited_check when is_cfn_template(%INPUT_DOCUMENT) %lambda_layer_permissions not empty { check(%lambda_layer_permissions.Properties) << [CT.LAMBDA.PR.4]: Require an AWS Lambda layer permission to grant access to an AWS organization or specific Conta da AWS [FIX]: Set the 'OrganizationId' parameter to the ID of an AWS organization, or set the 'Principal' parameter to an Conta da AWS ID. >> } rule lambda_layer_public_access_prohibited_check when is_cfn_hook(%INPUT_DOCUMENT, %LAMBDA_LAYER_PERMISSION_TYPE) { check(%INPUT_DOCUMENT.%LAMBDA_LAYER_PERMISSION_TYPE.resourceProperties) << [CT.LAMBDA.PR.4]: Require an AWS Lambda layer permission to grant access to an AWS organization or specific Conta da AWS [FIX]: Set the 'OrganizationId' parameter to the ID of an AWS organization, or set the 'Principal' parameter to an Conta da AWS ID. >> } # # Parameterized Rules # rule check(lambda_layer_permission) { %lambda_layer_permission [ OrganizationId not exists ] { # Scenarios 2 and 3 Principal exists check_is_string_and_not_empty(Principal) Principal != "*" } %lambda_layer_permission [ OrganizationId exists ] { # Scenario 4 check_is_string_and_not_empty(OrganizationId) } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_is_string_and_not_empty(value) { %value { this is_string this != /\A\s*\z/ } }

Modelos de exemplo do CT.LAMBDA.PR.4

Você pode ver exemplos dos artefatos de teste PASS e FAIL para os controles proativos do AWS Control Tower.

Exemplo de PASS - Use esse modelo para verificar a criação de um recurso compatível.

Resources: LayerVersion: Type: AWS::Lambda::LayerVersion Properties: CompatibleRuntimes: - python3.9 Content: S3Bucket: example-layer-bucket S3Key: layer.zip Description: Example layer LayerName: example-layer LicenseInfo: MIT LayerVersionPermission: Type: AWS::Lambda::LayerVersionPermission Properties: Action: lambda:GetLayerVersion LayerVersionArn: Ref: LayerVersion OrganizationId: o-abc123defg Principal: "*"

Exemplo de FALHA - Use esse modelo para verificar se o controle impede a criação de recursos não compatíveis.

Resources: LayerVersion: Type: AWS::Lambda::LayerVersion Properties: CompatibleRuntimes: - python3.9 Content: S3Bucket: example-layer-bucket S3Key: layer.zip Description: Example layer LayerName: example-layer LicenseInfo: MIT LayerVersionPermission: Type: AWS::Lambda::LayerVersionPermission Properties: Action: lambda:GetLayerVersion LayerVersionArn: Ref: LayerVersion Principal: "*"

[CT.LAMBDA.PR.5] Exigir um URL de AWS Lambda função para usar a autenticação AWS baseada em IAM

Esse controle verifica se o URL de uma AWS Lambda função está configurado para usar a autenticação baseada no IAM.

  • Objetivo de controle: impor o menor privilégio

  • Implementação: regra de AWS CloudFormation guarda

  • Comportamento de controle: proativo

  • Tipos de recursos: AWS::Lambda::Url

  • AWS CloudFormation regra de guarda: Especificação da regra CT.LAMBDA.PR.5

Detalhes e exemplos

Explicação

Você pode controlar o acesso a uma URL de função Lambda usando o AuthType parâmetro, combinado com políticas baseadas em recursos que são anexadas à sua função específica. A configuração desses dois componentes determina quem pode invocar ou executar outras ações administrativas no URL de função.

O AuthType parâmetro determina como o Lambda autentica ou autoriza solicitações para o URL da função Lambda (endpoint). AuthTypeDefinir como NONE significa que o Lambda não executa nenhuma autenticação antes de invocar sua função. No entanto, a política baseada em recursos da sua função está sempre em vigor, e a política deve conceder acesso público antes que sua URL da função Lambda (endpoint) possa receber solicitações.

Remediação em caso de falha de regra

Defina o AuthType parâmetro como AWS_IAM

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda URL da função - Exemplo

Um URL de AWS Lambda função (endpoint) configurado com autenticação baseada em AWS IAM. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "FunctionUrl": { "Type": "AWS::Lambda::Url", "Properties": { "TargetFunctionArn": { "Fn::GetAtt": [ "LambdaFunction", "Arn" ] }, "AuthType": "AWS_IAM" } } }

Exemplo de YAML

FunctionUrl: Type: AWS::Lambda::Url Properties: TargetFunctionArn: !GetAtt 'LambdaFunction.Arn' AuthType: AWS_IAM

Especificação da regra CT.LAMBDA.PR.5

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # lambda_function_url_auth_check # # Description: # This control checks whether an AWS Lambda function URL is configured to use authentication that's based on AWS IAM. # # Reports on: # AWS::Lambda::Url # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Lambda function URL resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function URL resource # And: 'AuthType' has not been provided # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function URL resource # And: 'AuthType' been provided and set to a value other than 'AWS_IAM' # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function URL resource # And: 'AuthType' been provided and set to 'AWS_IAM' # Then: PASS # # Constants # let LAMBDA_FUNCTION_URL_TYPE = "AWS::Lambda::Url" let AUTHORIZED_AUTHENTICATION_TYPES = ["AWS_IAM"] let INPUT_DOCUMENT = this # # Assignments # let lambda_function_urls = Resources.*[ Type == %LAMBDA_FUNCTION_URL_TYPE ] # # Primary Rules # rule lambda_function_url_auth_check when is_cfn_template(%INPUT_DOCUMENT) %lambda_function_urls not empty { check(%lambda_function_urls.Properties) << [CT.LAMBDA.PR.5]: Require an AWS Lambda function URL to use AWS IAM-based authentication [FIX]: Set the 'AuthType' parameter to 'AWS_IAM' >> } rule lambda_function_url_auth_check when is_cfn_hook(%INPUT_DOCUMENT, %LAMBDA_FUNCTION_URL_TYPE) { check(%INPUT_DOCUMENT.%LAMBDA_FUNCTION_URL_TYPE.resourceProperties) << [CT.LAMBDA.PR.5]: Require an AWS Lambda function URL to use AWS IAM-based authentication [FIX]: Set the 'AuthType' parameter to 'AWS_IAM' >> } # # Parameterized Rules # rule check(lambda_function_url) { %lambda_function_url { # Scenario 2 AuthType exists # Scenarios 3 and 4 AuthType in %AUTHORIZED_AUTHENTICATION_TYPES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Modelos de exemplo do CT.LAMBDA.PR.5

Você pode ver exemplos dos artefatos de teste PASS e FAIL para os controles proativos do AWS Control Tower.

Exemplo de PASS - Use esse modelo para verificar a criação de um recurso compatível.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Code: ZipFile: "def handler(event, context):\n print(\"example\")\n" Runtime: python3.9 FunctionUrl: Type: AWS::Lambda::Url Properties: TargetFunctionArn: Fn::GetAtt: - LambdaFunction - Arn AuthType: AWS_IAM

Exemplo de FALHA - Use esse modelo para verificar se o controle impede a criação de recursos não compatíveis.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Code: ZipFile: "def handler(event, context):\n print(\"example\")\n" Runtime: python3.9 FunctionUrl: Type: AWS::Lambda::Url Properties: TargetFunctionArn: Fn::GetAtt: - LambdaFunction - Arn AuthType: NONE

[CT.LAMBDA.PR.6] Exigir uma política de URL CORS de AWS Lambda função para restringir o acesso a origens específicas

Esse controle verifica se o URL de uma AWS Lambda função está configurado com uma política de compartilhamento de recursos de origem cruzada (CORS) que não concede acesso a todas as origens.

  • Objetivo do controle: limitar o acesso à rede

  • Implementação: regra de AWS CloudFormation guarda

  • Comportamento de controle: proativo

  • Tipos de recursos: AWS::Lambda::Url

  • AWS CloudFormation regra de guarda: Especificação da regra CT.LAMBDA.PR.6

Detalhes e exemplos

Explicação

O Cross-Origin Resource Sharing (CORS) é um mecanismo baseado em um cabeçalho HTTP, que permite que um servidor indique qualquer origem (domínio, esquema ou porta) diferente da sua, a partir da qual um navegador deve permitir o carregamento de recursos.

Se você definir uma origem curinga (*) em uma política CORS, você permite que o código executado em navegadores de qualquer origem tenha acesso ao URL da sua função.

Remediação em caso de falha de regra

No Cors parâmetro, certifique-se de que o valor de AllowOrigins não contenha origens curinga (*http://*ehttps://*)

Os exemplos a seguir mostram como implementar essa remediação.

AWS Lambda URL da função - Exemplo

AWS Lambda URL da função configurada com uma política de compartilhamento de recursos de origem cruzada (CORS) que restringe o acesso a uma origem específica. O exemplo é mostrado em JSON e em YAML.

Exemplo de JSON

{ "FunctionUrl": { "Type": "AWS::Lambda::Url", "Properties": { "TargetFunctionArn": { "Fn::GetAtt": [ "LambdaFunction", "Arn" ] }, "AuthType": "AWS_IAM", "Cors": { "AllowOrigins": [ "https://example.com" ] } } } }

Exemplo de YAML

FunctionUrl: Type: AWS::Lambda::Url Properties: TargetFunctionArn: !GetAtt 'LambdaFunction.Arn' AuthType: AWS_IAM Cors: AllowOrigins: - https://example.com

Especificação da regra CT.LAMBDA.PR.6

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # lambda_function_url_cors_check # # Description: # This control checks whether an AWS Lambda function URL is configured with a cross-origin resource sharing (CORS) policy that does not grant access to all origins. # # Reports on: # AWS::Lambda::Url # # Evaluates: # AWS CloudFormation, AWS CloudFormation Hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Lambda function URL resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function URL resource # And: 'AllowOrigins' in 'Cors' has not been provided or has been provided as an empty list # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function URL resource # And: 'Cors' has been provided # And: 'AllowOrigins' in 'Cors' has been provided as a non-empty list # And: 'AllowOrigins' has an entry that contains a wildcard value '*' # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Lambda function URL resource # And: 'Cors' has been provided # And: 'AllowOrigins' in 'Cors' has been provided as a non-empty list # And: No entries in 'AllowOrigins' contain a wildcard value '*' # Then: PASS # # Constants # let LAMBDA_FUNCTION_URL_TYPE = "AWS::Lambda::Url" let INPUT_DOCUMENT = this # # Assignments # let lambda_function_urls = Resources.*[ Type == %LAMBDA_FUNCTION_URL_TYPE ] # # Primary Rules # rule lambda_function_url_cors_check when is_cfn_template(%INPUT_DOCUMENT) %lambda_function_urls not empty { check(%lambda_function_urls.Properties) << [CT.LAMBDA.PR.6]: Require an AWS Lambda function URL CORS policy to restrict access to specific origins [FIX]: In the 'Cors' parameter, ensure that the value of 'AllowOrigins' does not contain wildcard origins ('*', 'http://*' and 'https://*') >> } rule lambda_function_url_cors_check when is_cfn_hook(%INPUT_DOCUMENT, %LAMBDA_FUNCTION_URL_TYPE) { check(%INPUT_DOCUMENT.%LAMBDA_FUNCTION_URL_TYPE.resourceProperties) << [CT.LAMBDA.PR.6]: Require an AWS Lambda function URL CORS policy to restrict access to specific origins [FIX]: In the 'Cors' parameter, ensure that the value of 'AllowOrigins' does not contain wildcard origins ('*', 'http://*' and 'https://*') >> } # # Parameterized Rules # rule check(lambda_function_url) { %lambda_function_url[ # Scenario 2 filter_cors_origins(this) ] { Cors { # Scenarios 3 and 4 AllowOrigins[*] != /\*/ } } } rule filter_cors_origins(lambda_function_url) { %lambda_function_url { Cors exists Cors is_struct Cors { AllowOrigins exists AllowOrigins is_list AllowOrigins not empty } } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Modelos de exemplo do CT.LAMBDA.PR.6

Você pode ver exemplos dos artefatos de teste PASS e FAIL para os controles proativos do AWS Control Tower.

Exemplo de PASS - Use esse modelo para verificar a criação de um recurso compatível.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Code: ZipFile: "def handler(event, context):\n print(\"example\")\n" Runtime: python3.9 FunctionUrl: Type: AWS::Lambda::Url Properties: TargetFunctionArn: Fn::GetAtt: - LambdaFunction - Arn AuthType: AWS_IAM Cors: AllowOrigins: - https://example.com

Exemplo de FALHA - Use esse modelo para verificar se o controle impede a criação de recursos não compatíveis.

Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' LambdaFunction: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: LambdaFunctionRole.Arn Handler: index.handler Code: ZipFile: "def handler(event, context):\n print(\"example\")\n" Runtime: python3.9 FunctionUrl: Type: AWS::Lambda::Url Properties: TargetFunctionArn: Fn::GetAtt: - LambdaFunction - Arn AuthType: AWS_IAM Cors: AllowOrigins: - '*'