You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
aws:SourceArn is only populated when an AWS service makes a request on behalf of a resource — here, SNS delivering a notification. A direct ReceiveMessage call by any principal carries no aws:SourceArn, so the ArnLike condition cannot match and the statement never applies. Nobody can actually read the queue through this policy.
So this is not an exploitable exposure today. It is worth fixing for two reasons:
It is correct by accident. The safety comes entirely from a condition key that happens not to exist on the request, not from the permission being scoped. Relax or reorder that condition later and it becomes real, with nothing in the template signalling that the condition is load-bearing.
ReceiveMessage is meaningless here regardless. SNS only ever sends to a subscribed queue; it never receives. The action is not merely unreachable, it is not something the intended principal would ever need.
Removing it breaks nothing.aws:process-sqs polls with the worker's own IAM credentials, and same-account access is granted by the IAM identity, not by this resource policy. Resource policies are additive and matter for cross-account access, which this is not.
Why bother, given it is not exploitable
Same reasoning as N-11: this is a Principal: "*" on the account-linking queue, in a public repo, one file away from the SNS topic policy a reviewer has just finished reading. The number of reviewers who will read Principal: "*" + ReceiveMessage, not work through the aws:SourceArn semantics, and draw their own conclusion is not zero.
Suggested fix
Drop ReceiveMessage, and switch to naming the service principal rather than *:
- Sid: allow-sns-topsaEffect: AllowPrincipal:
Service: sns.amazonaws.comAction: SQS:SendMessageResource: !GetAtt TopsSQS.ArnCondition:
ArnEquals:
"aws:SourceArn": !Ref TopsSNSTopicArn # or the joined ARN as today
There is already a reference implementation in this repo: TopsQuarantineSQSPolicy in infra/cloud-stack/stackset/sns.topic.cfn.yaml, added in #106, uses exactly this shape.
While in there: the ARN is built with a wildcard region (arn:aws:sns:*:<account>:teemops-sns). The topic and queue are deployed together in one region, so ArnEquals on the concrete region is available and tighter than ArnLike on a wildcard.
Both files should change together, or core/sqs.cfn.yaml should be deleted if the EC2 path is no longer supported — worth deciding, since a second unexercised copy of a template is what #102 turned out to be.
Acceptance criteria
Given the main queue policy, when it is read, then no statement grants SQS:ReceiveMessage to any principal
Given the main queue policy, when it is read, then SendMessage is granted to the SNS service principal rather than to *, conditioned on the concrete topic ARN
Given a real install, when an account is linked end to end, then onboarding completes exactly as it does today — the poller reads via IAM, so this must be confirmed rather than assumed
Given infra/cloud-stack/core/sqs.cfn.yaml, when this lands, then it is either changed in step or deleted as unsupported, and which was chosen is recorded
Size: XS · Found 2026-08-02 alongside #100 / #101 while reading the queue policies; recorded in
docs/features/sns-topic-publish-authorization.mdunder "Adjacent findings".Problem
TopsMainSQSPolicygrantsSQS:ReceiveMessagetoPrincipal: "*"onteemops_main, in both copies of the queue template:infra/cloud-stack/core-docker/sqs.cfn.yaml:58— the self-hosted Docker pathinfra/cloud-stack/core/sqs.cfn.yaml:58— the older EC2 pathIt is dead permission, and that is the point
aws:SourceArnis only populated when an AWS service makes a request on behalf of a resource — here, SNS delivering a notification. A directReceiveMessagecall by any principal carries noaws:SourceArn, so theArnLikecondition cannot match and the statement never applies. Nobody can actually read the queue through this policy.So this is not an exploitable exposure today. It is worth fixing for two reasons:
ReceiveMessageis meaningless here regardless. SNS only ever sends to a subscribed queue; it never receives. The action is not merely unreachable, it is not something the intended principal would ever need.Removing it breaks nothing.
aws:process-sqspolls with the worker's own IAM credentials, and same-account access is granted by the IAM identity, not by this resource policy. Resource policies are additive and matter for cross-account access, which this is not.Why bother, given it is not exploitable
Same reasoning as N-11: this is a
Principal: "*"on the account-linking queue, in a public repo, one file away from the SNS topic policy a reviewer has just finished reading. The number of reviewers who will readPrincipal: "*"+ReceiveMessage, not work through theaws:SourceArnsemantics, and draw their own conclusion is not zero.Suggested fix
Drop
ReceiveMessage, and switch to naming the service principal rather than*:There is already a reference implementation in this repo:
TopsQuarantineSQSPolicyininfra/cloud-stack/stackset/sns.topic.cfn.yaml, added in #106, uses exactly this shape.While in there: the ARN is built with a wildcard region (
arn:aws:sns:*:<account>:teemops-sns). The topic and queue are deployed together in one region, soArnEqualson the concrete region is available and tighter thanArnLikeon a wildcard.Both files should change together, or
core/sqs.cfn.yamlshould be deleted if the EC2 path is no longer supported — worth deciding, since a second unexercised copy of a template is what #102 turned out to be.Acceptance criteria
SQS:ReceiveMessageto any principalSendMessageis granted to the SNS service principal rather than to*, conditioned on the concrete topic ARNinfra/cloud-stack/core/sqs.cfn.yaml, when this lands, then it is either changed in step or deleted as unsupported, and which was chosen is recorded