Skip to content

fix: reject malformed unsigned requests instead of crashing before signature check - #1586

Open
sahiljagtap08 wants to merge 1 commit into
slackapi:mainfrom
sahiljagtap08:fix/robust-context-extraction-1447
Open

sahiljagtap08 wants to merge 1 commit into
slackapi:mainfrom
sahiljagtap08:fix/robust-context-extraction-1447

Conversation

@sahiljagtap08

Copy link
Copy Markdown

Summary

Fixes #1447

Public endpoints get hit by scanners and bots that send any JSON shape. Bolt builds the request context (team id, user id, and so on) when the BoltRequest is created, which is before the RequestVerification middleware runs. A body with the wrong value types, a JSON array, or broken JSON raised TypeError, AttributeError, or JSONDecodeError. The result was a 500 for a request that should have been a 401.

This follows the non-breaking approach suggested in the issue thread: make the context extraction robust instead of moving it behind the middleware.

Changes:

  • Every extract_* helper in slack_bolt/request/internals.py checks the value type before using it (authorizations, enterprise, team, user, channel, event).
  • parse_body treats non-object JSON (array, string, number, null) and invalid JSON as an empty body, so the request still reaches the signature check and is rejected there.
  • build_context and build_async_context guard the shape of response_urls.
  • Comments explain why each guard exists.

Testing

  • New unit tests in tests/slack_bolt/request/test_internals.py cover the malformed shapes for every extractor, build_context, and parse_body.
  • New end-to-end tests in tests/scenario_tests/test_app.py and tests/scenario_tests_async/test_app.py send unsigned malformed bodies to App and AsyncApp and assert a 401 (previously an exception).
  • Ran ./scripts/format.sh, ./scripts/lint.sh, ./scripts/run_mypy.sh, and the full test suite. All existing tests pass.

Category

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components
  • Adapters in slack_bolt.adapter
  • Others

Requirements

  • I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've run ./scripts/install_all_and_run_tests.sh after making the changes.

@sahiljagtap08
sahiljagtap08 requested a review from a team as a code owner October 7, 2026 00:11
@salesforce-cla

salesforce-cla Bot commented Oct 7, 2026

Copy link
Copy Markdown

Thanks for the contribution! Before we can merge this, we need @sahiljagtap08 to sign the Salesforce Inc. Contributor License Agreement.

@srtaalej

srtaalej commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

thank you for opening this PR @sahiljagtap08 💟 looking pretty good! i'll give it a more thorough review once the CLA is signed and CI passes 😸

@sahiljagtap08

Copy link
Copy Markdown
Author

recheck

…gnature check

Non-Slack clients (scanners, bots) can send any JSON shape to a public
endpoint. Building the request context happens before the
RequestVerification middleware runs, so a body with unexpected value
types, a JSON array, or broken JSON used to raise TypeError,
AttributeError, or JSONDecodeError. That turned an unsigned request
into a 500 instead of the expected 401.

- Every extract_* helper now checks the value type before using it
- parse_body treats non-object or invalid JSON as an empty body
- build_context / build_async_context guard the response_urls shape
- Add unit tests for the malformed shapes and end-to-end tests that
  assert a 401 for both App and AsyncApp

Fixes slackapi#1447
@sahiljagtap08
sahiljagtap08 force-pushed the fix/robust-context-extraction-1447 branch from 9acb04f to afd575d Compare October 8, 2026 00:09
@sahiljagtap08

Copy link
Copy Markdown
Author

@srtaalej thanks for taking a look! The CLA is signed now and the check is passing. Let me know if you'd like any changes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

extract_team_id crashes with TypeError when payload["user"] is a string (e.g. member_joined_channel events)

2 participants