Skip to content

feat(slack): add subtype field and signature verification to Slack trigger#4030

Merged
waleedlatif1 merged 2 commits intostagingfrom
waleedlatif1/slack-trigger-audit
Apr 8, 2026
Merged

feat(slack): add subtype field and signature verification to Slack trigger#4030
waleedlatif1 merged 2 commits intostagingfrom
waleedlatif1/slack-trigger-audit

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add subtype, channel_type, and bot_id output fields to the Slack webhook trigger so users can differentiate real messages from system messages (e.g., "left #channel")
  • Add verifyAuth using HMAC-SHA256 signature verification with 5-minute replay protection — the signing secret field already existed but was never actually used
  • Update setup instructions to mention message.channels, message.im, message.mpim, message.groups event subscriptions

Type of Change

  • New feature (non-breaking, purely additive)

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 8, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 8, 2026 0:58am

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 8, 2026

PR Summary

Medium Risk
Adds security-critical Slack webhook signature verification with timestamp replay protection, which could reject previously accepted requests if headers/secrets are misconfigured or clocks skewed. Output schema changes are additive but may affect downstream workflows that rely on missing/empty values.

Overview
Slack webhook requests are now authenticated. The Slack webhook provider adds verifyAuth that enforces Slack’s x-slack-signature HMAC-SHA256 check (constant-time compare) and rejects requests with missing headers or >5-minute timestamp skew.

Slack trigger payload is richer and docs are updated. The Slack webhook trigger and Slack block outputs add subtype, channel_type, and bot_id to help distinguish system/bot messages, and the setup instructions now mention subscribing to message.* events for channels/DMs/groups.

Reviewed by Cursor Bugbot for commit d921909. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 8, 2026

Greptile Summary

This PR enhances the Slack webhook trigger in two meaningful ways: it activates HMAC-SHA256 signature verification (the signing secret field existed before but was ignored), and it exposes three new output fields — subtype, channel_type, and bot_id — so workflows can differentiate system messages from real user messages.

Key changes:

  • Signature verification (lib/webhooks/providers/slack.ts): verifyAuth now validates x-slack-signature using validateSlackSignature with constant-time comparison via safeCompare, and rejects requests with a timestamp skew > 5 minutes. A Number.isNaN guard (added in the head commit) prevents malformed timestamps from bypassing the replay window.
  • New output fields (lib/webhooks/providers/slack.ts, blocks/blocks/slack.ts, triggers/slack/webhook.ts): subtype, channel_type, and bot_id are extracted from the raw Slack event and default to '', consistent with all pre-existing optional string fields.
  • Setup instructions (triggers/slack/webhook.ts): Updated to mention message.channels, message.im, message.mpim, and message.groups event subscriptions.

Prior review concerns about the NaN replay-window bypass and the null vs '' sentinel mismatch have both been addressed in the head commit. The one remaining issue is that the user-facing field descriptions for subtype and bot_id still say "Null for regular user messages" / "Null for human users", which contradicts the '' fallback now in effect.

Confidence Score: 5/5

Safe to merge — all P0/P1 concerns from prior rounds are resolved; only minor description-string inconsistencies remain.

The core security implementation (HMAC verification, replay protection, NaN guard, constant-time comparison) is correct and complete. The sentinel-value inconsistency flagged in a previous round is fixed. The only remaining findings are P2 stale description strings ("Null for..." vs the actual '' fallback) that don't affect runtime behavior.

Minor description wording in apps/sim/triggers/slack/webhook.ts and apps/sim/blocks/blocks/slack.ts (lines referencing "Null for..." on fields that actually return empty string).

Vulnerabilities

  • HMAC-SHA256 signing-secret verification is added correctly: the basestring format matches Slack's spec (v0:{timestamp}:{rawBody}), safeCompare (constant-time) prevents timing-oracle attacks, and the v0= prefix is stripped before comparison.
  • The 5-minute replay window is validated before the HMAC check, and a Number.isNaN guard prevents a malformed timestamp from silently bypassing the window (previously flagged and now fixed).
  • When signingSecret is absent, verifyAuth returns null (allow-through) rather than rejecting. This is an intentional opt-in design (existing webhooks configured without a secret continue to work), but operators should be aware that omitting the secret disables all request authentication.

Important Files Changed

Filename Overview
apps/sim/lib/webhooks/providers/slack.ts Adds HMAC-SHA256 verifyAuth with correct basestring format, constant-time comparison, 5-minute replay window, and Number.isNaN guard; also adds subtype, channel_type, bot_id output fields with '' fallback matching existing conventions.
apps/sim/triggers/slack/webhook.ts Adds subtype, channel_type, bot_id to the trigger output schema and expands setup instructions; descriptions for subtype and bot_id still say "Null for..." but the runtime value is ''.
apps/sim/blocks/blocks/slack.ts Adds subtype, channel_type, bot_id to the block's trigger output descriptors; same "Null for..." wording inconsistency as the trigger file.

Sequence Diagram

sequenceDiagram
    participant Slack
    participant WebhookRoute
    participant slackHandler
    participant validateSlackSignature

    Slack->>WebhookRoute: POST /webhook (x-slack-signature, x-slack-request-timestamp, body)
    WebhookRoute->>slackHandler: handleChallenge(body)
    slackHandler-->>WebhookRoute: null (not a challenge) or 200 challenge response

    WebhookRoute->>slackHandler: verifyAuth({ request, rawBody, providerConfig })
    slackHandler->>slackHandler: check signingSecret present
    slackHandler->>slackHandler: read x-slack-signature and x-slack-request-timestamp
    slackHandler->>slackHandler: Number.isNaN(parsedTimestamp)?
    alt invalid timestamp
        slackHandler-->>WebhookRoute: 401 Invalid timestamp
    end
    slackHandler->>slackHandler: |now - parsedTimestamp| > 300s?
    alt timestamp too old
        slackHandler-->>WebhookRoute: 401 Request timestamp too old
    end
    slackHandler->>validateSlackSignature: (signingSecret, signature, timestamp, rawBody)
    validateSlackSignature->>validateSlackSignature: HMAC-SHA256(v0:{ts}:{body})
    validateSlackSignature->>validateSlackSignature: safeCompare(computed, provided)
    validateSlackSignature-->>slackHandler: true / false
    alt invalid signature
        slackHandler-->>WebhookRoute: 401 Invalid Slack signature
    end
    slackHandler-->>WebhookRoute: null (auth passed)

    WebhookRoute->>slackHandler: formatInput({ body, webhook })
    slackHandler->>slackHandler: extract event_type, subtype, channel_type, bot_id, user, text, files
    slackHandler-->>WebhookRoute: { input: { event: { subtype, channel_type, bot_id, ... } } }
    WebhookRoute->>WebhookRoute: enqueue workflow execution
    WebhookRoute-->>Slack: 200 OK
Loading

Reviews (2): Last reviewed commit: "fix(slack): guard against NaN timestamp ..." | Re-trigger Greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d921909. Configure here.

@waleedlatif1 waleedlatif1 merged commit e0f5cf8 into staging Apr 8, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/slack-trigger-audit branch April 8, 2026 01:13
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