Skip to content

fix(worker): bind Slack API auth to a server-side session - #36

Merged
StephenTangCook merged 1 commit into
mainfrom
posthog-self-driving/fixworker-bind-slack-api-auth-to-server-1447fc
Aug 27, 2026
Merged

fix(worker): bind Slack API auth to a server-side session#36
StephenTangCook merged 1 commit into
mainfrom
posthog-self-driving/fixworker-bind-slack-api-auth-to-server-1447fc

Conversation

@posthog

@posthog posthog Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Who is hurt: anyone who knows a workspace's Slack team ID can read its private channel list and post as its bot — a pre-authentication token-disclosure flaw that every fork of this public template inherits.
  • Root cause: the SPA-facing endpoints trusted the bkb_team_id and bkb_user_id cookies as identity. cookies.ts writes them as plaintext, unsigned, with no server-side record, so a client can set them and load the bot token from KV. The same pattern loaded a member's user token in the sendAsUser branch.
  • Fix: mint a random session ID at both OAuth callbacks, store { team_id, user_id } server-side in the new SLACK_SESSIONS KV under that ID, and set only the opaque ID as the bkb_session cookie. Every protected endpoint resolves identity through the session, never from client-supplied values.

Reachable through /api/slack/channels, /api/slack/emojis, /api/slack/messages/send, /api/slack/modals/send, and the /api/slack/me/can-send-as-user enumeration oracle.

Path Before After
requireBotInstall team ID read from bkb_team_id cookie team ID read from the server-side session
sendAsUser / modal send user ID read from bkb_user_id cookie user ID read from the session
can-send-as-user open oracle — any forged cookie pair answered answers only for a valid session

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Docs
  • Build / CI / deps
  • Other

Area

  • Builder UI / React SPA (src/)
  • Bot OAuth (/slack/install)
  • User-token OAuth (/slack/user-install)
  • Worker API routes (/api/slack/*)
  • Slack events ingress (/slack/events)
  • Setup scripts (scripts/)
  • Deploy / CI (.github/workflows, wrangler.jsonc)
  • Docs

Test plan

  • pnpm run build passes
  • pnpm run dev:tunnel exercised end-to-end where relevant
  • Manual checks listed below

Manual checks:

  • pnpm run build bundles the worker and client.
  • pnpm run typecheck reports only the pre-existing src/client/App.tsx prop-type error (present on clean main, unrelated to this change); no errors in the worker.

Screenshots / recordings

N/A — server-side auth change, no UI.

Related issues

Closes ENG-5917, ENG-5918 (linked in the footer).

Checklist

  • No secrets, tokens, or signing keys committed
  • Updated README.md / .dev.vars.example / wrangler.jsonc if config or setup changed
  • Considered backwards compatibility for existing forks of the template

Important

Breaking setup change for forks. This adds a fifth KV namespace, SLACK_SESSIONS. Forks must run pnpm run setup:kv again and paste the new ID into wrangler.jsonc (the REPLACE_WITH_SESSIONS_KV_ID placeholder). After deploy, the old bkb_team_id / bkb_user_id cookies stop working; users re-run /slack/install (and /slack/user-install for "send as me") to get a session. Stored installations in KV stay valid.

Agent context

  • Instrumentation for rejected sessions (suggested in the report) was left out on purpose: it would add a telemetry SDK to a public template, which is a maintainer decision beyond this P0 fix. The worker already logs to wrangler tail / pnpm run logs.

Created with PostHog Desktop from this inbox report, addressing ENG-5917, ENG-5918.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

The SPA-facing worker endpoints trusted the `bkb_team_id` and `bkb_user_id`
cookies as proof of identity. Both cookies were plaintext with no signature
and no server-side record, so a client could set them and reach any
workspace's bot token and any consented member's user token.

Mint a random session id at both OAuth callbacks, store `{team_id, user_id}`
in the new SLACK_SESSIONS KV under it, and set only that opaque id as the
`bkb_session` cookie. Every protected endpoint now resolves identity through
the session, never from client-supplied values.

Closes ENG-5917, ENG-5918.

Generated-By: PostHog Desktop
Task-Id: 14ad785e-882d-4ab1-afca-6b829e1f2421
@StephenTangCook
StephenTangCook marked this pull request as ready for review August 27, 2026 16:06
@StephenTangCook
StephenTangCook merged commit 3695f41 into main Aug 27, 2026
3 checks passed
@StephenTangCook
StephenTangCook deleted the posthog-self-driving/fixworker-bind-slack-api-auth-to-server-1447fc branch August 27, 2026 16:08
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.

1 participant