Skip to main content

Ensure EventBridge Event Bus Is Not Publicly Exposed

Overview

This check verifies that your Amazon EventBridge event buses do not have overly permissive resource policies that allow public access. An event bus is considered "exposed" when its policy contains Principal: "*" without proper conditions, allowing any AWS account to send events to your bus.

Risk

If your EventBridge event bus is publicly exposed:

  • Unauthorized event injection: Attackers can send malicious events that trigger your downstream targets (Lambda functions, Step Functions, etc.)
  • Data exposure: Triggered targets may process or expose sensitive data
  • Service disruption: High-volume event injection can overwhelm your systems
  • Cost escalation: Attackers can drive up costs by flooding your bus with events
  • Lateral movement: Compromised events can be used as a stepping stone to other resources

Severity: High

Remediation Steps

Prerequisites

You need permission to view and modify EventBridge event bus policies. Typically this requires the events:DescribeEventBus, events:PutPermission, and events:RemovePermission IAM permissions.

AWS Console Method

  1. Open the Amazon EventBridge console at https://console.aws.amazon.com/events/
  2. In the left navigation, click Event buses
  3. Select the event bus flagged by Prowler
  4. Click the Permissions tab
  5. Review the resource policy - look for statements where Principal is "*" without restrictive conditions
  6. Click Edit policy (or Manage permissions)
  7. Either:
    • Remove statements that grant public access, or
    • Replace "*" with specific account ARNs (e.g., arn:aws:iam::123456789012:root)
  8. Click Save
AWS CLI (optional)

View Current Policy

First, check the current event bus policy:

aws events describe-event-bus \
--name <your-event-bus-name> \
--region us-east-1

For the default event bus, omit the --name parameter:

aws events describe-event-bus --region us-east-1

The output includes a Policy field (JSON string) showing all permission statements.

Remove a Specific Permission

If you know the statement ID of the problematic permission:

aws events remove-permission \
--event-bus-name <your-event-bus-name> \
--statement-id <statement-id> \
--region us-east-1

Remove All Permissions

To remove all permissions from an event bus (use with caution):

aws events remove-permission \
--event-bus-name <your-event-bus-name> \
--remove-all-permissions \
--region us-east-1

Add Restricted Permission

To grant access to a specific AWS account:

aws events put-permission \
--event-bus-name <your-event-bus-name> \
--statement-id "AllowAccount123456789012" \
--action "events:PutEvents" \
--principal "123456789012" \
--region us-east-1

To grant access to all accounts in your AWS Organization:

aws events put-permission \
--event-bus-name <your-event-bus-name> \
--statement-id "AllowMyOrganization" \
--action "events:PutEvents" \
--principal "*" \
--condition "Type=StringEquals,Key=aws:PrincipalOrgID,Value=o-xxxxxxxxxx" \
--region us-east-1
CloudFormation (optional)

Use this template to create a secure event bus with a properly restricted policy:

AWSTemplateFormatVersion: '2010-09-09'
Description: Secure EventBridge event bus with restricted resource policy

Parameters:
EventBusName:
Type: String
Default: my-secure-event-bus
Description: Name of the EventBridge event bus

TrustedAccountId:
Type: String
Description: AWS Account ID allowed to send events to this bus
AllowedPattern: '^[0-9]{12}$'

Resources:
SecureEventBus:
Type: AWS::Events::EventBus
Properties:
Name: !Ref EventBusName

EventBusPolicy:
Type: AWS::Events::EventBusPolicy
Properties:
EventBusName: !Ref SecureEventBus
StatementId: AllowTrustedAccount
Action: events:PutEvents
Principal: !Ref TrustedAccountId

Outputs:
EventBusArn:
Description: ARN of the secure event bus
Value: !GetAtt SecureEventBus.Arn
EventBusName:
Description: Name of the secure event bus
Value: !Ref SecureEventBus

Deploy with:

aws cloudformation deploy \
--template-file template.yaml \
--stack-name secure-eventbridge-bus \
--parameter-overrides \
EventBusName=my-secure-event-bus \
TrustedAccountId=123456789012 \
--region us-east-1
Terraform (optional)
# Secure EventBridge Event Bus with Restricted Policy
# This configuration creates an event bus that only allows
# specific AWS accounts to send events

variable "event_bus_name" {
description = "Name of the EventBridge event bus"
type = string
default = "my-secure-event-bus"
}

variable "trusted_account_ids" {
description = "List of AWS Account IDs allowed to send events"
type = list(string)
}

resource "aws_cloudwatch_event_bus" "secure_bus" {
name = var.event_bus_name
}

resource "aws_cloudwatch_event_bus_policy" "secure_policy" {
event_bus_name = aws_cloudwatch_event_bus.secure_bus.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowTrustedAccounts"
Effect = "Allow"
Principal = {
AWS = [for account_id in var.trusted_account_ids : "arn:aws:iam::${account_id}:root"]
}
Action = "events:PutEvents"
Resource = aws_cloudwatch_event_bus.secure_bus.arn
}
]
})
}

output "event_bus_arn" {
description = "ARN of the secure event bus"
value = aws_cloudwatch_event_bus.secure_bus.arn
}

output "event_bus_name" {
description = "Name of the secure event bus"
value = aws_cloudwatch_event_bus.secure_bus.name
}

Create a terraform.tfvars file:

event_bus_name      = "my-secure-event-bus"
trusted_account_ids = ["123456789012", "987654321098"]

Apply with:

terraform init
terraform plan
terraform apply

Verification

After remediation, verify that the event bus policy is properly restricted:

  1. Return to the EventBridge console > Event buses
  2. Select your event bus and click the Permissions tab
  3. Confirm that:
    • No statements have Principal: "*" without conditions
    • All principals are specific account ARNs or properly conditioned
CLI Verification
aws events describe-event-bus \
--name <your-event-bus-name> \
--region us-east-1 \
--query 'Policy' \
--output text | jq .

Look for any "Principal": "*" entries. If found, ensure they have proper Condition blocks (e.g., aws:PrincipalOrgID).

Re-run the Prowler check to confirm the issue is resolved:

prowler aws --check eventbridge_bus_exposed

Additional Resources

Notes

  • Default event bus: Every AWS account has a default event bus. If your default bus is exposed, the remediation steps are the same, but omit the --event-bus-name parameter in CLI commands or leave it empty in the console.

  • Cross-account event delivery: If you legitimately need to receive events from other accounts, use specific account IDs or restrict access using AWS Organizations conditions (aws:PrincipalOrgID) rather than Principal: "*".

  • Partner event sources: Some AWS partner integrations require specific permissions. Consult the partner's documentation before modifying policies that may affect these integrations.

  • Impact assessment: Before removing permissions, identify any external accounts or services that may be sending events to your bus. Removing their access will cause their event delivery to fail.