AWS EventBridge event bus policy does not allow public access
EventBridge event bus resource policy is evaluated for public access, such as a Principal: "*" or overly broad conditions that allow any AWS account to publish events or manage rules on the bus.
Risk
Publicly accessible event buses enable event injection and unauthorized rule changes, undermining integrity and enabling lateral movement. Attackers can trigger downstream targets, causing data exposure, service disruption, and unexpected costs through high-volume events.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks eventbridge_bus_exposedRecommendation
Apply least privilege resource policies: limit principals to specific accounts or your organization, and constrain actions and event attributes (e.g., source, detail-type). Avoid Principal: "*".
Use defense in depth with rule patterns that include the expected account. Monitor policy changes and bus activity.
Remediation
CLI
aws events remove-permission --event-bus-name <event_bus_name> --statement-id <statement_id>Terraform
resource "aws_cloudwatch_event_bus_policy" "<example_resource_name>" {
# CRITICAL: Principal is a specific AWS account, not "*", preventing public access
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowSpecificAccount",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<example_account_id>:root"},
"Action": "events:PutEvents",
"Resource": "arn:aws:events:<example_region>:<example_account_id>:event-bus/default"
}]
}
POLICY
}NativeIaC
# CloudFormation: restrict EventBridge event bus access to a specific account (not public)
Resources:
<example_resource_name>:
Type: AWS::Events::EventBusPolicy
Properties:
StatementId: AllowSpecificAccount
Action: events:PutEvents
Principal: arn:aws:iam::<example_account_id>:root # CRITICAL: limit access to a specific AWS account to prevent public access
# Omitting EventBusName applies this to the default event busOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.eventbridge.eventbridge_client import (
eventbridge_client,
)
from prowler.providers.aws.services.iam.lib.policy import is_policy_public
class eventbridge_bus_exposed(Check):
def execute(self):
findings = []
for bus in eventbridge_client.buses.values():
if bus.policy is None:
continue
report = Check_Report_AWS(metadata=self.metadata(), resource=bus)
report.status = "PASS"
report.status_extended = (
f"EventBridge event bus {bus.name} is not exposed to everyone."
)
if is_policy_public(bus.policy, eventbridge_client.audited_account):
report.status = "FAIL"
report.status_extended = (
f"EventBridge event bus {bus.name} is exposed to everyone."
)
findings.append(report)
return findingsReferences
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEvents-CrossAccountEventDelivery.html
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CWE_GettingStarted.html
- https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/aws/CloudWatchEvents/event-bus-exposed.html
- https://aws.amazon.com/blogs/compute/simplifying-cross-account-access-with-amazon-eventbridge-resource-policies/