AWS Lambda Function Policy Updated to Allow Public Invocation
ELASTIC detection rule by Elastic · Elastic License v2
Identifies when an AWS Lambda function policy is updated to allow public invocation. This rule detects use of the
AddPermission API where the Principal is set to "*", enabling any AWS account to invoke the function. Adversaries may
abuse this configuration to establish persistence, create a covert execution path, or operate a function as an
unauthenticated backdoor. Public invocation is rarely required outside very specific workloads and should be considered
high-risk when performed unexpectedly.
[metadata]
creation_date = "2024/04/30"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/05"
[rule]
author = ["Elastic"]
description = """
Identifies when an AWS Lambda function policy is updated to allow public invocation. This rule detects use of the
AddPermission API where the Principal is set to "*", enabling any AWS account to invoke the function. Adversaries may
abuse this configuration to establish persistence, create a covert execution path, or operate a function as an
unauthenticated backdoor. Public invocation is rarely required outside very specific workloads and should be considered
high-risk when performed unexpectedly.
"""
event_category_override = "event.type"
false_positives = [
"""
Some organizations may legitimately expose Lambda functions for cross-account or anonymous invocation (e.g., custom
public APIs, integrations, or legacy architectures). Validate whether the function owner explicitly intended to make
the function publicly invokable. Routine CI/CD deployments or IaC templates may also temporarily set permissive
policies; confirm this is expected behavior before treating it as suspicious.
""",
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "eql"
license = "Elastic License v2"
name = "AWS Lambda Function Policy Updated to Allow Public Invocation"
note = """## Triage and analysis
### Investigating AWS Lambda Function Policy Updated to Allow Public Invocation
AWS Lambda policies control who can invoke a function. When the `Principal` is set to `*`, the function becomes publicly invokable by any AWS account. Adversaries may modify Lambda permissions to create a stealthy execution backdoor or to maintain persistence inside an AWS environment. This activity is uncommon in most production environments and should receive careful scrutiny when detected.
### Possible investigation steps
**Identify the actor**
- Identify the actor who made the change by reviewing `aws.cloudtrail.user_identity.arn` and access key ID. Determine whether this principal typically administers Lambda functions.
**Review request details**
- Review request details in `aws.cloudtrail.request_parameters` to understand the exact permission added:
- Confirm that the `Principal` is set to `"*"`.
- Note the `Action` (`lambda:InvokeFunction`) and any `SourceArn` restrictions (sometimes present, often missing in malicious cases).
**Analyze source context**
- Check the source of the request using `source.ip`, geo information, and user agent. Unexpected networks, automation tools, or CLI usage may indicate credential compromise.
**Correlate timing and related events**
- Evaluate timing and sequence by correlating `@timestamp` with other events. Look for surrounding actions such as:
- Creation or update of Lambda function code.
- Publishing new Lambda layers.
- Changes to roles attached to the function.
**Assess function sensitivity and impact**
- Assess the function’s role and data sensitivity. Determine whether public invocation could:
- Enable unmonitored code execution,
- Trigger access to internal resources via the function’s IAM role,
- Be chained with persistence or privilege escalation behavior.
**Validate operational intent**
- Validate the operational context. Confirm with the function owner whether the permission change was intentional, part of a deployment, or unexpected.
### False positive analysis
- Public invocation may be intentional for certain workloads (e.g., webhook handlers, openly accessible compute functions). Compare the event with documentation, IaC templates, or the deployment pipeline.
- Some teams may regularly modify permissions during testing or refactoring; check whether this aligns with existing workflows.
- Evaluate whether the function already had permissive invocation policies and whether the update is part of expected configuration drift.
### Response and remediation
- Remove unauthorized public invocation permissions immediately by reverting the Lambda function policy to the approved baseline.
- Investigate for follow-on activity: execution of the function, updates to code, modifications to IAM roles, or API calls issued using the function's role.
- Rotate or disable credentials associated with the identity that issued the `AddPermission` call if compromise is suspected.
- Enable or refine monitoring for Lambda policy updates, layer additions, and code changes to detect future unauthorized modifications.
- Conduct a security review of the Lambda function and any downstream resources it can access to ensure no misuse has occurred.
- Work with the application team to enforce least-privilege invocation policies and deploy guardrails (e.g., SCPs, IAM Conditions, or automated compliance checks) preventing public invocation unless explicitly authorized.
### Additional information
- **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/)**
- **[AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework/tree/a8c7b313636b406a375952ac00b2d68e89a991f2/docs)**
- **[AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/)**
"""
references = [
"https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence",
"https://stratus-red-team.cloud/attack-techniques/AWS/aws.persistence.lambda-backdoor-function/",
"https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html",
]
risk_score = 73
rule_id = "151d8f72-0747-11ef-a0c2-f661ea17fbcc"
severity = "high"
tags = [
"Domain: Cloud",
"Platform: AWS",
"Data Source: AWS CloudTrail",
"Service: AWS Lambda",
"Tactic: Persistence",
"Rule Type: Event Correlation (EQL)",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
info where data_stream.dataset == "aws.cloudtrail"
and event.provider == "lambda.amazonaws.com"
and event.outcome == "success"
and event.action : "AddPermission*"
and stringContains(aws.cloudtrail.request_parameters, "lambda:InvokeFunction")
and stringContains(aws.cloudtrail.request_parameters, "principal=\\*")
and not user_agent.original like~ ("*Terraform*", "*Pulumi*")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1578"
name = "Modify Cloud Compute Infrastructure"
reference = "https://attack.mitre.org/techniques/T1578/"
[[rule.threat.technique.subtechnique]]
id = "T1578.005"
name = "Modify Cloud Compute Configurations"
reference = "https://attack.mitre.org/techniques/T1578/005/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements",
]