Skip to content

feat: add CSRF nonce to Slack OAuth state parameter #946

Merged
thomaswhyyou merged 17 commits intomainfrom
thomas-kno-12535-slackkit-add-automatic-csrf-nonce-support-to-slack-oauth
Apr 10, 2026
Merged

feat: add CSRF nonce to Slack OAuth state parameter #946
thomaswhyyou merged 17 commits intomainfrom
thomas-kno-12535-slackkit-add-automatic-csrf-nonce-support-to-slack-oauth

Conversation

@thomaswhyyou
Copy link
Copy Markdown
Contributor

@thomaswhyyou thomaswhyyou commented Apr 10, 2026

Description

A customer reported that Slack's app review process requires a nonce in the OAuth state parameter: https://knocklabs.slack.com/archives/C06FHSQ18G4/p1775582016010559

In this PR we now generate a random nonce via crypto.randomUUID and include in the state param when building the auth URL, store it in sessionStorage, and verify it against the nonce echoed back in the postMessage payload.

Note, the postMessage listener accepts both the legacy raw string ("authComplete") and a new structured format ({ type, nonce }) for backward compatibility with older API versions that haven't been updated yet.

There is a corresponding PR in switchboard that echoes back the provided nonce: https://github.com/knocklabs/switchboard/pull/6104

@linear
Copy link
Copy Markdown

linear bot commented Apr 10, 2026

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
javascript-ms-teams-connect-example Ready Ready Preview, Comment Apr 10, 2026 11:33pm
javascript-nextjs-example Ready Ready Preview, Comment Apr 10, 2026 11:33pm
javascript-slack-connect-example Ready Ready Preview, Comment Apr 10, 2026 11:33pm
javascript-slack-kit-example Ready Ready Preview, Comment Apr 10, 2026 11:33pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 10, 2026

🦋 Changeset detected

Latest commit: 22f5bd0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@knocklabs/react-core Patch
@knocklabs/react Patch
@knocklabs/expo Patch
@knocklabs/react-native Patch
guide-example Patch
ms-teams-connect-example Patch
nextjs-app-dir-example Patch
nextjs-example Patch
slack-connect-example Patch
slack-kit-example Patch
@knocklabs/expo-example Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@thomaswhyyou
Copy link
Copy Markdown
Contributor Author

@cursor review

@thomaswhyyou
Copy link
Copy Markdown
Contributor Author

@cursor review

@thomaswhyyou
Copy link
Copy Markdown
Contributor Author

@cursor review

@thomaswhyyou thomaswhyyou marked this pull request as ready for review April 10, 2026 16:55
@thomaswhyyou thomaswhyyou requested review from a team and removed request for a team April 10, 2026 16:55
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9d524a1. Configure here.

nonceStorageKey: getSlackNonceStorageKey(
knockSlackChannelId,
knock.userId!,
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Polling path bypasses CSRF nonce verification entirely

Medium Severity

useAuthPolling runs concurrently alongside useAuthPostMessageListener in SlackAuthButton and can detect auth success via server-side polling, setting the connection status to "connected" and calling onAuthenticationComplete without any CSRF nonce verification. This provides an alternative success path that completely bypasses the nonce check this PR adds. The stored nonce in sessionStorage is also never cleaned up when polling detects success.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9d524a1. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thomaswhyyou thomaswhyyou force-pushed the thomas-kno-12535-slackkit-add-automatic-csrf-nonce-support-to-slack-oauth branch from 9d524a1 to 22f5bd0 Compare April 10, 2026 23:31
@thomaswhyyou thomaswhyyou merged commit 4863fe5 into main Apr 10, 2026
13 checks passed
@thomaswhyyou thomaswhyyou deleted the thomas-kno-12535-slackkit-add-automatic-csrf-nonce-support-to-slack-oauth branch April 10, 2026 23:45
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.04%. Comparing base (463f85b) to head (22f5bd0).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #946      +/-   ##
==========================================
+ Coverage   63.85%   64.04%   +0.19%     
==========================================
  Files         209      209              
  Lines       10007    10060      +53     
  Branches     1281     1297      +16     
==========================================
+ Hits         6390     6443      +53     
  Misses       3592     3592              
  Partials       25       25              
Files with missing lines Coverage Δ
packages/react-core/src/index.ts 100.00% <ø> (ø)
...c/modules/core/hooks/useAuthPostMessageListener.ts 100.00% <100.00%> (ø)
...ckages/react-core/src/modules/slack/hooks/index.ts 100.00% <100.00%> (ø)
...react-core/src/modules/slack/hooks/useSlackAuth.ts 97.05% <100.00%> (+0.42%) ⬆️
packages/react-core/src/modules/slack/index.ts 100.00% <ø> (ø)
...ack/components/SlackAuthButton/SlackAuthButton.tsx 76.72% <100.00%> (+0.83%) ⬆️

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.

3 participants