Use the Conformity Knowledge Base AI to help improve your Cloud Posture

SQS Queue Exposed

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: High (act today)
Rule ID: SQS-001

Identify any publicly accessible Amazon SQS queues and update their permissions in order to protect against unauthorized users.

This rule can help you with the following compliance standards:

  • PCI
  • GDPR
  • APRA
  • MAS

For further details on compliance standards supported by Conformity, see here.

This rule can help you work with the AWS Well-Architected Framework.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

Allowing anonymous users to have access to your Amazon SQS queues can lead to unauthorized actions such as intercepting, deleting, and sending compromised queue messages. One common scenario is when the queue owner grants permissions to everyone by setting the Principal to Everybody (i.e. "*") while testing the queue system configuration and the insecure set of permissions reach into production. To avoid data leakage and unexpected costs on your AWS bill, limit access to your SQS queues by implementing the right permissions.


Audit

To determine if your Amazon SQS queues are publicly accessible, perform the following operations:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon SQS console at https://console.aws.amazon.com/sqs/.

03 In the main navigation panel, under Amazon SQS, choose Queues.

04 Click on the name (link) of the SQS queue that you want to examine.

05 Select the Access policy tab from the console bottom panel to access the permissions defined for the selected queue.

06 Check the policy document listed in the Access policy (Permissions) section. If the "Effect" element value is set to "Allow", the "Principal" element value is set to "*" or {"AWS": "*"}, and the policy is not using IP-based "Condition" clauses to filter the access, as shown in the policy example listed below, the selected Amazon OpenSearch domain is publicly accessible (i.e. accessible to everyone):

{
  "Version": "2012-10-17",
  "Id": "sqs-queue-access",
  "Statement": [
    {
      "Sid": "public-access",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SQS:SendMessage",
        "SQS:ReceiveMessage",
        "SQS:DeleteMessage",
        "SQS:PurgeQueue"
      ],
      "Resource": "arn:aws:sqs:us-east-1:123456789012:cc-web-app-worker"
    }
  ]
}

07 Repeat steps no. 4 – 6 for each Amazon SQS queue available within the current AWS region.

08 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.

Using AWS CLI

01 Run list-queues command (OSX/Linux/UNIX) to list the URL of each Amazon SQS queue available in the selected AWS cloud region:

aws sqs list-queues
  --region us-east-1
  --query 'QueueUrls[*]'

02 The command output should return an array with the requested SQS queue URLs:

[
    "https://sqs.us-east-1.amazonaws.com/123456789012/cc-web-app-worker",
    "https://sqs.us-east-1.amazonaws.com/123456789012/cc-mobile-app-queue"
]

03 Run get-queue-attributes command (OSX/Linux/UNIX) using the URL of the SQS queue that you want to examine as the identifier parameter and custom query filters to describe the access policy defined for the selected SQS queue:

aws sqs get-queue-attributes
  --region us-east-1
  --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/cc-web-app-worker
  --attribute-names "Policy"
  --query 'Attributes.Policy'

04 The command output should return the requested policy document:

{
  "Version": "2012-10-17",
  "Id": "sqs-queue-access",
  "Statement": [
    {
      "Sid": "public-access",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SQS:SendMessage",
        "SQS:ReceiveMessage",
        "SQS:DeleteMessage",
        "SQS:PurgeQueue"
      ],
      "Resource": "arn:aws:sqs:us-east-1:123456789012:cc-web-app-worker"
    }
  ]
}

Check the policy document returned by the get-queue-attributes command output. If the "Effect" element value is set to "Allow", the "Principal" element value is set to "*" or {"AWS": "*"}, and the policy is not using IP-based "Condition" clauses to filter the access, as shown in the policy example listed above, the selected Amazon SQS queue is publicly accessible.

05 Repeat steps no. 3 and 4 for each Amazon SQS queue available in the selected AWS region.

06 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 5 to perform the Audit process for other regions.

Remediation / Resolution

To update the custom policies and set the appropriate permissions to secure any exposed SQS queues, perform the following:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Description": "Secure Exposed Amazon SQS Queue",
	"Parameters": {
		"SQSQueueName": {
			"Default": "cc-worker-queue",
			"Description": "SQS Worker Queue",
			"Type": "String",
			"MinLength": "1",
			"MaxLength": "63",
			"AllowedPattern": "^[0-9a-zA-Z-/]*$",
			"ConstraintDescription": "Must begin with a letter and must not end with a hyphen or contain two consecutive hyphens."
		}
	},
	"Resources": {
		"SQSDeadLetterQueue": {
			"Type": "AWS::SQS::Queue"
		},
		"SQSSourceQueue": {
			"Type": "AWS::SQS::Queue",
			"Properties": {
				"QueueName": {
					"Ref": "SQSQueueName"
				},
				"RedrivePolicy": {
					"deadLetterTargetArn": {
						"Fn::GetAtt": ["SQSDeadLetterQueue", "Arn"]
					},
					"maxReceiveCount": 5
				}
			}
		},
		"SQSAccessPolicy" : {
			"Type" : "AWS::SQS::QueuePolicy",
			"Properties" : {
				"PolicyDocument": {
					"Version": "2012-10-17",
					"Id": "sqs-queue-access",
					"Statement": [
						{
							"Sid": "public-access",
							"Effect": "Allow",
							"Principal": {
								"AWS": "arn:aws:iam::123456789012:user/queue_manager"
							},
							"Action": [
								"SQS:SendMessage",
								"SQS:ReceiveMessage",
								"SQS:DeleteMessage",
								"SQS:PurgeQueue"
							],
							"Resource": "arn:aws:sqs:us-east-1:123456789012:cc-web-app-worker"
						}
					]
				},
				"Queues":  [{
					"Ref": "SQSSourceQueue"
				}]
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Description: Secure Exposed Amazon SQS Queue
	Parameters:
		SQSQueueName:
		Default: cc-worker-queue
		Description: SQS Worker Queue
		Type: String
		MinLength: '1'
		MaxLength: '63'
		AllowedPattern: ^[0-9a-zA-Z-/]*$
		ConstraintDescription: Must begin with a letter and must not end with a hyphen
			or contain two consecutive hyphens.
	Resources:
		SQSDeadLetterQueue:
		Type: AWS::SQS::Queue
		SQSSourceQueue:
		Type: AWS::SQS::Queue
		Properties:
			QueueName: !Ref 'SQSQueueName'
			RedrivePolicy:
			deadLetterTargetArn: !GetAtt 'SQSDeadLetterQueue.Arn'
			maxReceiveCount: 5
		SQSAccessPolicy:
		Type: AWS::SQS::QueuePolicy
		Properties:
			PolicyDocument:
			Version: '2012-10-17'
			Id: sqs-queue-access
			Statement:
				- Sid: public-access
				Effect: Allow
				Principal:
					AWS: arn:aws:iam::123456789012:user/queue_manager
				Action:
					- SQS:SendMessage
					- SQS:ReceiveMessage
					- SQS:DeleteMessage
					- SQS:PurgeQueue
				Resource: arn:aws:sqs:us-east-1:123456789012:cc-web-app-worker
			Queues:
			- !Ref 'SQSSourceQueue'

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
	required_providers {
		aws = {
			source  = "hashicorp/aws"
			version = "~> 3.27"
		}
	}

	required_version = ">= 0.14.9"
}

provider "aws" {
	profile = "default"
	region  = "us-east-1"
}

resource "aws_sqs_queue" "sqs-queue-deadletter" {
	name = "cc-dead-letter-queue"
}

resource "aws_sqs_queue" "sqs-queue" {
	name                  = "sqs-worker-queue"
	redrive_policy = jsonencode({
		deadLetterTargetArn = aws_sqs_queue.sqs-queue-deadletter.arn
		maxReceiveCount     = 5
	})
}

# Secure Exposed Amazon SQS Queue
resource "aws_sqs_queue_policy" "sqs-queue-policy" {
	queue_url = aws_sqs_queue.sqs-queue.id
	policy = <<POLICY
	{
		"Version": "2012-10-17",
		"Id": "sqs-queue-access",
		"Statement": [
			{
				"Sid": "public-access",
				"Effect": "Allow",
				"Principal": {
					"AWS": "arn:aws:iam::123456789012:user/queue_manager"
				},
				"Action": [
					"SQS:SendMessage",
					"SQS:ReceiveMessage",
					"SQS:DeleteMessage",
					"SQS:PurgeQueue"
				],
				"Resource": "arn:aws:sqs:us-east-1:123456789012:cc-web-app-worker"
			}
		]
	}
	POLICY
}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon SQS console at https://console.aws.amazon.com/sqs/.

03 In the main navigation panel, under Amazon SQS, choose Queues.

04 Click on the name (link) of the SQS queue that you want to reconfigure.

05 Select the Access policy tab from the console bottom panel and choose Edit.

06 On the Edit <queue-name> configuration page, within the Access policy section, perform one of the following actions based on your requirements:

  1. To disable the public access to the selected SQS queue, delete the entire policy document listed in the Access policy editor box or remove just the policy statement that allows public access. Choose Save to apply the policy changes.
  2. To limit the access to a specific AWS account or IAM user, replace the "Principal" element value with the Amazon Resource Name (ARN) of the trusted AWS account, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:root" } or the IAM user, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:user/<user-name>" } that should have access to the selected Amazon SQS queue. Choose Save to apply the changes
  3. To limit the queue access to a specific (trusted) IP address/IP range, add a "Condition" clause to the policy statement, i.e. "Condition": { "IpAddress": { "aws:SourceIp": "<ipv4-address>" } }, where <ipv4-address> is the trusted IPv4 address that can access the selected SQS queue. Choose Save to apply the policy changes.

07 Repeat steps no. 4 – 6 for other Amazon SQS queues available within the current AWS region.

08 Change the AWS cloud region from the navigation bar and repeat the Remediation process for other AWS regions.

Using AWS CLI

01 Modify the access policy attached to your Amazon SQS queue and replace the "Principal" element value (i.e. "*") with the ARN of the trusted AWS account, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:root" } or the IAM user, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:user/<user-name>" } that should have access to the selected SQS queue. Save the policy document to a JSON file named trusted-access-policy.json. You can also add a "Condition" clause to the policy statement to limit the domain access to a specific (trusted) IP address/IP range only. As an example, the following access policy allows access to an IAM user identified by the ARN "arn:aws:iam::123456789012:user/queue_manager" (highlighted):

{
"Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"sqs-queue-access\",\"Statement\":[{\"Sid\":\"trusted-access\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:user/queue_manager\"},\"Action\":[\"SQS:SendMessage\",\"SQS:ReceiveMessage\",\"SQS:DeleteMessage\",\"SQS:PurgeQueue\"],\"Resource\":\"arn:aws:sqs:us-east-1:123456789012:cc-web-app-worker\"}]}"
}

02 Run set-queue-attributes command (OSX/Linux/UNIX) using the URL of the Amazon SQS queue that you want to reconfigure as the identifier parameter to replace the existing access policy with the one modified at the previous step (i.e. trusted-access-policy.json):

aws sqs set-queue-attributes
  --region us-east-1
  --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/cc-web-app-worker
  --attributes file://trusted-access-policy.json

03 Repeat steps no. 1 and 2 for other Amazon SQS queues available in the selected AWS region.

04 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 3 to perform the Remediation process for other regions.

References

Publication date Apr 23, 2016