AWS Lambda Function Policy Updated to Allow Cross-Account Invocation

Identifies a change to an AWS Lambda function resource policy that grants invoke permissions to an AWS account principal. Using AddPermission, an adversary can authorize a principal in another account to call a function, creating a cross-account backdoor for execution or for relaying data to attacker-controlled infrastructure without modifying the function's code. This rule excludes public grants (principal set to "*"), which are covered by a separate rule, and grants to AWS service principals, which are common for legitimate event triggers.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/06/18"
  3integration = ["aws"]
  4maturity = "production"
  5updated_date = "2026/06/18"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies a change to an AWS Lambda function resource policy that grants invoke permissions to an AWS account principal.
 11Using AddPermission, an adversary can authorize a principal in another account to call a function, creating a
 12cross-account backdoor for execution or for relaying data to attacker-controlled infrastructure without modifying the
 13function's code. This rule excludes public grants (principal set to "*"), which are covered by a separate rule, and
 14grants to AWS service principals, which are common for legitimate event triggers.
 15"""
 16false_positives = [
 17    """
 18    Cross-account invoke permissions are used for legitimate multi-account architectures and partner integrations.
 19    Verify the granted account in `aws.cloudtrail.request_parameters`, the function, and the `principal` value in
 20    `aws.cloudtrail.request_parameters` against approved cross-account access. Known partner or internal account ids can
 21    be excluded after validation. This rule cannot distinguish a grant to the function's own account from an external
 22    account, so same-account resource-policy grants (uncommon, since same-account invocation normally uses IAM
 23    identity-based policies) will also alert.
 24    """,
 25]
 26from = "now-6m"
 27index = ["logs-aws.cloudtrail-*"]
 28language = "eql"
 29license = "Elastic License v2"
 30name = "AWS Lambda Function Policy Updated to Allow Cross-Account Invocation"
 31note = """## Triage and analysis
 32
 33### Investigating AWS Lambda Function Policy Updated to Allow Cross-Account Invocation
 34
 35AWS Lambda resource policies control which principals may invoke a function. `AddPermission` granting `lambda:InvokeFunction` to a principal in another AWS account creates a cross-account invocation path. Adversaries use this to maintain execution access or to relay function output to infrastructure they control, without changing the function code that defenders typically scrutinize.
 36
 37This rule detects grants of invoke permission to a specific external account, excluding public grants (handled by the related public-invocation rule) and AWS service principals used for normal event triggers.
 38
 39### Possible investigation steps
 40
 41- Inspect `aws.cloudtrail.request_parameters` for the `functionName`, the `action` granted, and the `principal` account id receiving access; confirm whether that account is known and trusted.
 42- Identify the actor in `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.type`, and review `source.ip` and `user_agent.original` to understand how the change was made.
 43- Determine whether the function processes or has access to sensitive data that the external account could now reach.
 44- Correlate with other activity by the same principal, including function code or configuration changes and additional policy modifications.
 45- Verify whether the cross-account grant aligns with an approved integration or change request.
 46
 47### False positive analysis
 48
 49- Multi-account architectures and partner integrations legitimately grant cross-account invoke permissions. Confirm the grant is approved and exclude known trusted account ids or service roles on `aws.cloudtrail.user_identity.arn` after validation.
 50
 51### Response and remediation
 52
 53- If the grant is unauthorized, remove the statement from the function's resource policy (`RemovePermission`) and review the function's code, configuration, and execution role.
 54- Determine whether the external account invoked the function while the grant was in place and assess data exposure.
 55- Rotate or restrict credentials for the principal if compromise is suspected, and constrain `lambda:AddPermission` to a small set of trusted roles.
 56
 57### Additional information
 58
 59- [Lambda resource-based policies](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html)
 60- [AddPermission API](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html)
 61"""
 62references = [
 63    "https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html",
 64    "https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html",
 65]
 66risk_score = 73
 67rule_id = "8f985da6-66e8-4838-a63e-21636eb9adc5"
 68severity = "high"
 69tags = [
 70    "Domain: Cloud",
 71    "Data Source: AWS",
 72    "Data Source: Amazon Web Services",
 73    "Data Source: AWS Lambda",
 74    "Use Case: Threat Detection",
 75    "Tactic: Persistence",
 76    "Tactic: Defense Evasion",
 77    "Resources: Investigation Guide",
 78]
 79timestamp_override = "event.ingested"
 80type = "eql"
 81
 82query = '''
 83any where data_stream.dataset == "aws.cloudtrail"
 84    and event.provider == "lambda.amazonaws.com"
 85    and event.outcome == "success"
 86    and event.action : "AddPermission*"
 87    and stringContains(aws.cloudtrail.request_parameters, "lambda:InvokeFunction")
 88    and not stringContains(aws.cloudtrail.request_parameters, "principal=\\*")
 89    and not stringContains(aws.cloudtrail.request_parameters, ".amazonaws.com")
 90'''
 91
 92
 93[[rule.threat]]
 94framework = "MITRE ATT&CK"
 95[[rule.threat.technique]]
 96id = "T1546"
 97name = "Event Triggered Execution"
 98reference = "https://attack.mitre.org/techniques/T1546/"
 99
100
101[rule.threat.tactic]
102id = "TA0003"
103name = "Persistence"
104reference = "https://attack.mitre.org/tactics/TA0003/"
105[[rule.threat]]
106framework = "MITRE ATT&CK"
107[[rule.threat.technique]]
108id = "T1578"
109name = "Modify Cloud Compute Infrastructure"
110reference = "https://attack.mitre.org/techniques/T1578/"
111[[rule.threat.technique.subtechnique]]
112id = "T1578.005"
113name = "Modify Cloud Compute Configurations"
114reference = "https://attack.mitre.org/techniques/T1578/005/"
115
116
117
118[rule.threat.tactic]
119id = "TA0005"
120name = "Defense Evasion"
121reference = "https://attack.mitre.org/tactics/TA0005/"
122
123[rule.investigation_fields]
124field_names = [
125    "@timestamp",
126    "user.name",
127    "user_agent.original",
128    "source.ip",
129    "aws.cloudtrail.user_identity.arn",
130    "aws.cloudtrail.user_identity.type",
131    "aws.cloudtrail.user_identity.access_key_id",
132    "aws.cloudtrail.user_identity.session_context.session_issuer.arn",
133    "aws.cloudtrail.request_parameters",
134    "aws.cloudtrail.response_elements",
135    "event.action",
136    "event.outcome",
137    "cloud.account.id",
138    "cloud.region",
139]

Triage and analysis

Investigating AWS Lambda Function Policy Updated to Allow Cross-Account Invocation

AWS Lambda resource policies control which principals may invoke a function. AddPermission granting lambda:InvokeFunction to a principal in another AWS account creates a cross-account invocation path. Adversaries use this to maintain execution access or to relay function output to infrastructure they control, without changing the function code that defenders typically scrutinize.

This rule detects grants of invoke permission to a specific external account, excluding public grants (handled by the related public-invocation rule) and AWS service principals used for normal event triggers.

Possible investigation steps

  • Inspect aws.cloudtrail.request_parameters for the functionName, the action granted, and the principal account id receiving access; confirm whether that account is known and trusted.
  • Identify the actor in aws.cloudtrail.user_identity.arn and aws.cloudtrail.user_identity.type, and review source.ip and user_agent.original to understand how the change was made.
  • Determine whether the function processes or has access to sensitive data that the external account could now reach.
  • Correlate with other activity by the same principal, including function code or configuration changes and additional policy modifications.
  • Verify whether the cross-account grant aligns with an approved integration or change request.

False positive analysis

  • Multi-account architectures and partner integrations legitimately grant cross-account invoke permissions. Confirm the grant is approved and exclude known trusted account ids or service roles on aws.cloudtrail.user_identity.arn after validation.

Response and remediation

  • If the grant is unauthorized, remove the statement from the function's resource policy (RemovePermission) and review the function's code, configuration, and execution role.
  • Determine whether the external account invoked the function while the grant was in place and assess data exposure.
  • Rotate or restrict credentials for the principal if compromise is suspected, and constrain lambda:AddPermission to a small set of trusted roles.

Additional information

References

Related rules

to-top