Skip to content

pubsub/awssnssqs: verify SNS envelope shape before trusting it - #3762

Merged
vangent merged 2 commits into
google:masterfrom
herdiyana256:fix-awssnssqs-sns-envelope-verification
Jul 31, 2026
Merged

pubsub/awssnssqs: verify SNS envelope shape before trusting it#3762
vangent merged 2 commits into
google:masterfrom
herdiyana256:fix-awssnssqs-sns-envelope-verification

Conversation

@herdiyana256

Copy link
Copy Markdown
Contributor

extractBody() decides a raw SQS message body is an SNS notification by unmarshalling it as JSON and checking for a non-empty TopicArn field. If it matches, the envelope's MessageAttributes become the delivered message's Metadata and the body is replaced by the envelope's Message field — nothing about the envelope's origin is checked.

This runs for every awssqs:// subscription that doesn't set Raw: true (the default), including ones that only ever expect SNS-delivered traffic. Since SQS message bodies are attacker-influenced whenever anything upstream forwards user data into the queue (or the attacker simply has sqs:SendMessage), a body shaped like {"TopicArn":"anything","Message":"...","MessageAttributes":{...}} lets the sender choose the Metadata the subscriber sees, or swap out the delivered body for something the real bytes never contained — despite Metadata looking like it was authoritatively set by SNS.

This requires the shape an actual SNS notification has (Type: "Notification", MessageId, Timestamp, TopicArn) before unwrapping, and adds SubscriptionOptions.SNSTopicARN (settable via the snstopicarn URL parameter) so a subscription can additionally pin the topic it expects and ignore envelopes claiming a different one. Existing conformance tests (recorded against real SNS/SQS traffic) still pass unmodified since real notifications already have all four fields.

extractBody() treated any JSON body with a non-empty TopicArn field as an SNS
notification, took its MessageAttributes as the message's Metadata, and
replaced the body with its Message field. A producer that can only set the
raw SQS message body (sqs:SendMessage, or any upstream that forwards
attacker-influenced JSON into the queue) could forge that shape and inject
arbitrary Metadata the subscriber would treat as coming from SNS, or silently
swap out the delivered body.

Require the fields SNS notifications actually carry (Type="Notification",
MessageId, Timestamp, TopicArn) before unwrapping, and add
SubscriptionOptions.SNSTopicARN (also settable via the snstopicarn URL
parameter) so a subscription can pin the expected topic and reject envelopes
claiming a different one.
…heck

Each of the 3 added cases omits exactly one of the four required fields
(Type, MessageId, Timestamp already covered structurally; here MessageId,
Timestamp, and a wrong Type value), confirming extractBody actually requires
all four rather than a subset that happens to pass the existing tests.
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.39%. Comparing base (65c466d) to head (8be298a).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
pubsub/awssnssqs/awssnssqs.go 75.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3762   +/-   ##
=======================================
  Coverage   75.38%   75.39%           
=======================================
  Files         104      104           
  Lines       14241    14250    +9     
=======================================
+ Hits        10736    10744    +8     
  Misses       2768     2768           
- Partials      737      738    +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vangent
vangent merged commit 7654671 into google:master Jul 31, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants