PostHog / PostHog/posthog

Harden SES webhook: allowlist SNS TopicArn after signature verification

Open
#61,644 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
39.9k
Forks
3.4k
Avg merge
6h 51m
Merged PRs (30d)
232

Description

Background

Follow-up from #60229 (email tracking code signing). The SES event webhook (/public/m/ses_webhook) verifies the SNS message signature, which proves the envelope was signed by some AWS SNS topic - but not that it came from our SES notification topic. The handler also auto-confirms any sns.<region>.amazonaws.com subscription.

Gap

An attacker can create their own SNS topic, get our endpoint to auto-confirm it, then publish a signed Bounce notification with a forged tracking tag - reaching recipientsManager.optOut for a team. A valid signature alone doesn't stop this.

This is pre-existing (not introduced by #60229). #60229 mitigates the main vector over time by signing tracking codes (once unsigned codes are rejected, a forged bounce needs a code that decodes to a valid team), but a residual recipient-replay vector remains, and the auto-confirm of foreign topics is itself undesirable.

Fix

After signature verification (and before auto-confirm / notification handling), reject envelopes whose TopicArn is not in an allowlist of our SES notification topic ARNs.

  • New config CDP_SES_WEBHOOK_ALLOWED_TOPIC_ARNS (comma-separated), parsed into a set in nodejs/src/cdp/services/messaging/helpers/ses.ts.
  • Empty default = allow-all (+ warn), so the code can ship before the env is configured; enforcement turns on once charts sets the var per env. No code redeploy needed to enable.
  • Wire the env per environment in charts to the sns_topic_arn output of the ses-events Terraform module (differs by region/account).

Related

  • Also track here: enforce signed tracking codes (reject unsigned) once existing in-flight unsigned links have aged out. That closes the broader forged-event surface.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in nodejs/src/cdp/services/messaging/helpers/ses.ts and trace the SES webhook flow from signature verification through auto-confirmation and notification handling. Then inspect the charts configuration and the ses-events Terraform module's sns_topic_arn output; done means the allowlist is parsed and enforced in the stated order, warns while empty, and is wired per environment.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, node.js, terraform
Domain
backend, cloud, infrastructure, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.