Skip to main content

SQS Queue Policy Does Not Allow Public Access

Overview

This check ensures that your Amazon SQS (Simple Queue Service) queues do not have policies that allow public access. A queue is considered publicly accessible when its policy contains Allow statements with wildcard (*) principals without restrictive conditions.

SQS queues often contain sensitive application data, transaction records, or system events. Making them publicly accessible creates significant security risks.

Risk

If an SQS queue is publicly accessible, anyone on the internet can potentially:

  • Read your messages: Sensitive data like customer information, API keys, or business transactions could be exposed
  • Send unauthorized messages: Attackers could inject malicious messages into your application workflow
  • Delete or purge messages: Critical messages could be removed, disrupting your application
  • Rack up costs: Unlimited message ingestion could result in unexpected AWS charges

This is classified as a critical severity finding because it directly exposes your data to the public internet.

Remediation Steps

Prerequisites

You need permission to modify SQS queue policies. Typically, this requires the sqs:SetQueueAttributes permission.

Required IAM permissions

To remediate this finding, your IAM user or role needs these permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:GetQueueAttributes",
"sqs:SetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:ListQueues"
],
"Resource": "*"
}
]
}

AWS Console Method

  1. Sign in to the AWS Console and navigate to SQS (Simple Queue Service)

  2. Select the queue that was flagged in the Prowler finding

  3. Click the Access policy tab

  4. Click Edit

  5. Review the current policy. Look for statements that have:

    • "Principal": "*" or "Principal": {"AWS": "*"}
    • "Effect": "Allow"
    • No restrictive Condition block
  6. Replace the wildcard principal with a specific AWS account or IAM role. For example, change:

    "Principal": "*"

    to:

    "Principal": {
    "AWS": "arn:aws:iam::123456789012:root"
    }
  7. Click Save

  8. Verify the change by reviewing the policy again

AWS CLI (optional)

Step 1: Get the current queue policy

aws sqs get-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue \
--attribute-names Policy \
--region us-east-1

Step 2: Create a secure policy file

Create a file named secure-policy.json:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
],
"Resource": "arn:aws:sqs:us-east-1:123456789012:my-queue"
}
]
}

Step 3: Apply the secure policy

aws sqs set-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue \
--attributes file://secure-policy-attributes.json \
--region us-east-1

Where secure-policy-attributes.json contains:

{
"Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AllowAccountAccess\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"},\"Action\":[\"sqs:SendMessage\",\"sqs:ReceiveMessage\",\"sqs:DeleteMessage\",\"sqs:GetQueueAttributes\"],\"Resource\":\"arn:aws:sqs:us-east-1:123456789012:my-queue\"}]}"
}

Alternative: Single-line command

aws sqs set-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue \
--attributes 'Policy={"Version":"2012-10-17","Statement":[{"Sid":"AllowAccountAccess","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"sqs:*","Resource":"arn:aws:sqs:us-east-1:123456789012:my-queue"}]}' \
--region us-east-1

Replace:

  • 123456789012 with your AWS account ID
  • my-queue with your queue name
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: Secure SQS Queue with restricted access policy

Parameters:
QueueName:
Type: String
Description: Name of the SQS queue
Default: my-secure-queue

AllowedAccountId:
Type: String
Description: AWS Account ID allowed to access the queue
Default: '123456789012'

Resources:
SecureSQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Ref QueueName
VisibilityTimeout: 30
MessageRetentionPeriod: 345600

SecureSQSQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
Queues:
- !Ref SecureSQSQueue
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowAccountAccess
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AllowedAccountId}:root'
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
- sqs:GetQueueAttributes
- sqs:GetQueueUrl
Resource: !GetAtt SecureSQSQueue.Arn

Outputs:
QueueUrl:
Description: URL of the SQS queue
Value: !Ref SecureSQSQueue

QueueArn:
Description: ARN of the SQS queue
Value: !GetAtt SecureSQSQueue.Arn

Deploy the stack:

aws cloudformation deploy \
--template-file template.yaml \
--stack-name secure-sqs-queue \
--parameter-overrides \
QueueName=my-secure-queue \
AllowedAccountId=123456789012 \
--region us-east-1
Terraform (optional)

Option 1: Apply a policy to an existing queue

resource "aws_sqs_queue_policy" "secure_policy" {
queue_url = "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue"

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowAccountAccess"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::123456789012:root"
}
Action = "sqs:*"
Resource = "arn:aws:sqs:us-east-1:123456789012:my-queue"
}
]
})
}

Option 2: Create a new secure queue

resource "aws_sqs_queue" "secure_queue" {
name = "secure-queue"
}

resource "aws_sqs_queue_policy" "secure_queue_policy" {
queue_url = aws_sqs_queue.secure_queue.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowSpecificRole"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::123456789012:role/MyApplicationRole"
}
Action = [
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
]
Resource = aws_sqs_queue.secure_queue.arn
}
]
})
}

Replace:

  • 123456789012 with your AWS account ID
  • MyApplicationRole with the IAM role that needs access

Verification

After making changes, verify the queue is no longer publicly accessible:

  1. In the AWS Console, go to SQS and select your queue
  2. Click the Access policy tab
  3. Confirm the policy no longer contains "Principal": "*" without restrictive conditions
CLI verification commands
# Get the current policy
aws sqs get-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue \
--attribute-names Policy \
--region us-east-1 \
--query 'Attributes.Policy' \
--output text | python3 -m json.tool

Look for:

  • No "Principal": "*" statements without conditions
  • Principals should specify specific AWS accounts or IAM roles

Re-run Prowler to confirm remediation:

prowler aws --check sqs_queues_not_publicly_accessible --region us-east-1

Additional Resources

Notes

  • Policy propagation delay: Changes to queue policies can take up to 60 seconds to propagate throughout the SQS system
  • Application impact: Before restricting access, ensure all legitimate applications and services that need queue access are included in the policy
  • Cross-account access: If you need to grant access to another AWS account, specify their account ARN explicitly rather than using a wildcard
  • VPC endpoints: For additional security, consider using VPC endpoints to keep SQS traffic within your VPC and add aws:SourceVpc or aws:SourceVpce conditions to your policy
  • Condition blocks: If you must allow broader access, use condition blocks to restrict by source IP, VPC, or other attributes