Skip to content

teemops_main queue policy grants SQS:ReceiveMessage to Principal: "*" #109

Description

@kiwifellows

Size: XS · Found 2026-08-02 alongside #100 / #101 while reading the queue policies; recorded in docs/features/sns-topic-publish-authorization.md under "Adjacent findings".

Problem

TopsMainSQSPolicy grants SQS:ReceiveMessage to Principal: "*" on teemops_main, in both copies of the queue template:

  • infra/cloud-stack/core-docker/sqs.cfn.yaml:58 — the self-hosted Docker path
  • infra/cloud-stack/core/sqs.cfn.yaml:58 — the older EC2 path
- Sid: allow-sns-topsa
  Effect: Allow
  Principal: "*"
  Action:
    - SQS:SendMessage
    - SQS:ReceiveMessage
  Resource:
    - !GetAtt TopsSQS.Arn
  Condition:
    ArnLike:
      "aws:SourceArn":
        - arn:aws:sns:*:<account>:teemops-sns

It is dead permission, and that is the point

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:

  1. 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.
  2. 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-topsa
  Effect: Allow
  Principal:
    Service: sns.amazonaws.com
  Action: SQS:SendMessage
  Resource: !GetAtt TopsSQS.Arn
  Condition:
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    infrastructureCI, release, deployment, toolingroadmap:nextQueued behind the current milestonesecuritySecurity-relevant changesize/XSUnder a day

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions