Back to Checks
Lambda function does not use cross-account layers
awslambda_function_using_cross_account_layers
Service: awslambdaSeverity: high
OfficialBuilt-inVerified
Categories:software-supply-chain
Resource Type:AwsLambdaFunction
AWS Lambda functions use only layers published within the same AWS account, rather than layers owned by external accounts.
A Lambda layer bundles shared code or dependencies that are injected into the function execution environment at runtime.
Risk
A layer from an external account is a supply chain dependency outside your control. If that account is compromised or the layer is updated maliciously, every consumer function executes attacker code with its IAM role — a direct privilege escalation and lateral movement path across all functions using that layer.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks awslambda_function_using_cross_account_layersRecommendation
Eliminate cross-account layer dependencies by hosting all layers in your own AWS account.
- Audit all layers with
aws lambda get-function-configurationand inspectLayers[].Arn - Extract the account ID from the ARN (field 5 in colon-split) and compare against your account
- For approved vendor layers, pin to a specific immutable version ARN and review on each update
- Enforce this via SCP: deny
lambda:UpdateFunctionConfigurationwhenlambda:LayerARN does not match your account ID
Remediation
CLI
# Copy the cross-account layer version into your own account first:
aws lambda publish-layer-version --layer-name <layer-name> --zip-file fileb://<layer.zip>
# Then update the function to use your own layer ARN:
aws lambda update-function-configuration --function-name <function-name> --layers <your-account-layer-arn>Terraform
resource "aws_lambda_layer_version" "example" {
layer_name = "<layer-name>"
filename = "<layer.zip>"
}
resource "aws_lambda_function" "example" {
function_name = "<example_resource_name>"
role = "<example_role_arn>"
handler = "index.handler"
runtime = "python3.12"
filename = "<example_package.zip>"
layers = [aws_lambda_layer_version.example.arn]
}NativeIaC
AWSTemplateFormatVersion: '2010-09-09'
Resources:
OwnedLayer:
Type: AWS::Lambda::LayerVersion
Properties:
LayerName: <layer-name>
Content:
S3Bucket: <bucket>
S3Key: <key>
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: <example_resource_name>
Role: <example_role_arn>
Handler: index.handler
Runtime: python3.12
Code:
S3Bucket: <example_code_bucket>
S3Key: <example_code_key>
Layers:
- !Ref OwnedLayerOther
1Download the cross-account layer ZIP
2Publish the layer in your own account: Lambda > Layers > Create layer
3Update the function configuration to reference your layer ARN
4Remove the cross-account layer ARN from the function
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.awslambda.awslambda_client import awslambda_client
class awslambda_function_using_cross_account_layers(Check):
def execute(self):
findings = []
for function in awslambda_client.functions.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=function)
cross_account_layers = [
layer
for layer in function.layers
if layer.account_id != awslambda_client.audited_account
]
if not function.layers:
report.status = "PASS"
report.status_extended = (
f"Lambda function {function.name} does not use any layers."
)
elif cross_account_layers:
report.status = "FAIL"
layer_arns = ", ".join(layer.arn for layer in cross_account_layers)
report.status_extended = (
f"Lambda function {function.name} uses cross-account "
f"layer(s): {layer_arns}."
)
else:
report.status = "PASS"
report.status_extended = (
f"Lambda function {function.name} only uses layers "
f"from the same account ({awslambda_client.audited_account})."
)
findings.append(report)
return findings