Detection rules › Kusto

AWS Security Hub - Detect SQS Queue policy allowing public access

Status
available
Severity
high
Time window
1h
Group by
AwsAccountId, AwsRegion, AwsSecurityFindingDescription, AwsSecurityFindingId, AwsSecurityFindingTitle, ComplianceSecurityControlId, QueueArn
Source
github.com/Azure/Azure-Sentinel

This query detects Amazon SQS queues with access policies that allow public (unauthenticated or cross-account unrestricted) access, using AWS Security Hub control SQS.3 findings. Publicly accessible queues can enable data exfiltration, unauthorized message injection, or disruption of workflows.

MITRE ATT&CK coverage

Rule body kusto

id: 4f0f3c2a-8d44-43f8-9d9a-5b1e0d5f2c11
name: AWS Security Hub - Detect SQS Queue policy allowing public access
description: |
  This query detects Amazon SQS queues with access policies that allow public (unauthenticated or cross-account unrestricted) access, using AWS Security Hub control SQS.3 findings.
  Publicly accessible queues can enable data exfiltration, unauthorized message injection, or disruption of workflows.
severity: High
status: Available
requiredDataConnectors:
  - connectorId: AWSSecurityHub
    dataTypes:
      - AWSSecurityHubFindings
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Exfiltration
  - Collection
relevantTechniques:
  - T1567
  - T1530
tags:
  - AWS Foundational Security Best Practices v1.0.0
query: |
  AWSSecurityHubFindings
  | where RecordState == "ACTIVE" and ComplianceStatus == "FAILED"
  | where tostring(AwsSecurityFindingGeneratorId) == "security-control/SQS.3"
        or tostring(ComplianceSecurityControlId) == "SQS.3"
  | mv-expand Resource = Resources
  | where tostring(Resource.Type) == "AwsSqsQueue"
  | extend QueueArn = tostring(Resource.Id)
  | summarize TimeGenerated = max(TimeGenerated)
      by AwsAccountId, AwsRegion, AwsSecurityFindingTitle, AwsSecurityFindingDescription,
         AwsSecurityFindingId, ComplianceSecurityControlId, QueueArn
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AwsAccountId
      - identifier: CloudAppAccountId
        columnName: AwsAccountId
  - entityType: CloudApplication
    fieldMappings:
      - identifier: Name
        columnName: QueueArn
customDetails:
  ComplianceControlId: ComplianceSecurityControlId
  Region: AwsRegion
  FindingId: AwsSecurityFindingId
  QueueArn: QueueArn
alertDetailsOverride:
  alertDisplayNameFormat: "Public access detected for SQS queue {{QueueArn}}"
  alertDescriptionFormat: |-
    AWS Account {{AwsAccountId}} has an SQS queue ({{QueueArn}}) with a policy permitting public access. Review and restrict the queue access policy.
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

AWSSecurityHubFindings

Stage 2: where

| where RecordState == "ACTIVE" and ComplianceStatus == "FAILED"

Stage 3: where

| where tostring(AwsSecurityFindingGeneratorId) == "security-control/SQS.3"
      or tostring(ComplianceSecurityControlId) == "SQS.3"

Stage 4: mv-expand

| mv-expand Resource = Resources

Stage 5: where

| where tostring(Resource.Type) == "AwsSqsQueue"

Stage 6: extend

| extend QueueArn = tostring(Resource.Id)

Stage 7: summarize

| summarize TimeGenerated = max(TimeGenerated)
    by AwsAccountId, AwsRegion, AwsSecurityFindingTitle, AwsSecurityFindingDescription,
       AwsSecurityFindingId, ComplianceSecurityControlId, QueueArn

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
AwsSecurityFindingGeneratorIdeq
  • security-control/SQS.3 transforms: tostring, cased
ComplianceSecurityControlIdeq
  • SQS.3 transforms: tostring, cased
ComplianceStatuseq
  • FAILED transforms: cased
RecordStateeq
  • ACTIVE transforms: cased
Typeeq
  • AwsSqsQueue transforms: tostring, cased

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
AwsAccountIdsummarize
AwsRegionsummarize
AwsSecurityFindingDescriptionsummarize
AwsSecurityFindingIdsummarize
AwsSecurityFindingTitlesummarize
ComplianceSecurityControlIdsummarize
QueueArnsummarize
TimeGeneratedsummarize