Skip to content

Slack: Stop unauthenticated requests from fataling the remaining webhook endpoints - #815

Closed
bor0 wants to merge 4 commits into
trunkfrom
fix/slack-webhook-hash-equals-type-error
Closed

Slack: Stop unauthenticated requests from fataling the remaining webhook endpoints#815
bor0 wants to merge 4 commits into
trunkfrom
fix/slack-webhook-hash-equals-type-error

Conversation

@bor0

@bor0 bor0 commented Aug 18, 2026

Copy link
Copy Markdown
Member

Summary

  • The #dotorg-alerts Slack channel reported repeated E_ERROR: Uncaught TypeError: hash_equals(): Argument #2 ($user_string) must be of type string fatals from community-deputies-calendly-webhook.php and trac-bot.php. Both pass $_GET['secret']/$_GET['token'] straight to hash_equals(), which requires a string in PHP 8 — a request like ?secret[]=x sends an array instead and fatals the endpoint rather than being rejected as invalid.
  • security-team.php has the same defect and is fixed here too. It did not show up in the alert batch because its dispatcher only runs when the request URI contains /security-team.php?token=, which filters out a bare ?token[]=x. A request like ?token=a&token[]=x satisfies that substring check while PHP overwrites the value with an array, so the endpoint throws the same TypeError.
  • announce.php, committers.php, and the array_combine() fatal in ticket.php reported in the same alert batch were already fixed by prior commits (announce.php/committers.php in ffdecba27, ticket.php in c05f7c3b4); this PR closes out the remaining call sites using the same guard pattern.

Notes

  • The two endpoints that bootstrap WordPress (trac-bot.php, community-deputies-calendly-webhook.php) compare the value through wp_unslash(), because wp_magic_quotes() has already slashed $_GET by the time the guard runs. security-team.php only loads hyperdb, so its request data is never slashed and the comparison stays on the raw value, with the WPCS unslash sniff annotated the way committers.php does it.
  • trac-bot.php's guard is split into a separate early return so all four webhook endpoints read alike. The calendly guard stays as a single condition, since splitting it would duplicate its header() + die() response in both branches.
  • subgroup.php was checked and needs no change — its signature comes from $_SERVER headers, which are always strings.

Test plan

  • php -l on all changed files
  • PHPCS on the changed files introduces no new violations
  • Confirm ?token[]=x / ?secret[]=x / ?token=a&token[]=x requests now return early instead of fataling in production

🤖 Generated with Claude Code

…ook endpoints.

hash_equals() requires string arguments in PHP 8. A request with an array-valued
secret/token param (e.g. ?secret[]=x) bypassed the empty()/?? guards and fatally
errored instead of being rejected, the same class of bug already fixed in
announce.php and committers.php.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props bor0, obenland.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@bor0
bor0 requested a review from obenland August 18, 2026 11:33
obenland and others added 2 commits August 18, 2026 09:55
security-team.php passes $_GET['token'] straight to hash_equals(), which
fatals on a non-string in PHP 8. The dispatcher gates on the request URI
containing '/security-team.php?token=', but '?token=a&token[]=x' satisfies
that check while PHP overwrites the value with an array, so the endpoint
still throws the same TypeError the rest of this branch fixes.

Guard the token the way announce.php and committers.php do. This file only
loads hyperdb, so the request is never slashed and the comparison stays on
the raw value, with the WPCS unslash sniff annotated accordingly.

Also split the inlined guard in trac-bot.php into the same shape, so all
four webhook endpoints read alike. No behaviour change there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The linter checks changed lines, and this file keeps its whole body flat
inside a curly-brace namespace, so the scope sniff reads every line as one
level short. That makes any edit inside the namespace fail regardless of
what it does, which is what the guard added in the previous commit ran into.

Give the file the header committers.php already carries: the reasons the
scope, nonce and unslash sniffs do not apply to a standalone server-to-server
endpoint, and a phpcs:disable for each. The inline unslash annotation is now
redundant, so drop it. Reindenting all 93 lines would fix the scope sniff for
real, but that belongs in its own change, not a crash fix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@obenland

Copy link
Copy Markdown
Member

Extended it to the remaining file and adjusted the checks to be in line with the prior fixes.

@bazza bazza closed this Aug 18, 2026
@bazza
bazza deleted the fix/slack-webhook-hash-equals-type-error branch August 18, 2026 20:44
@obenland
obenland restored the fix/slack-webhook-hash-equals-type-error branch August 18, 2026 20:46
@obenland obenland reopened this Aug 18, 2026
@obenland

Copy link
Copy Markdown
Member

Not sure what happened in #815 (comment)

@obenland

Copy link
Copy Markdown
Member

Oh, I know. @bor0 You need to create your PRs from a fork of this repo, not the repo itself. The hook that closes PRs when they get merged to meta SVN deletes all org-owned branches.

I merged #817 and it closed this one and #816 in one go.

@bor0

bor0 commented Aug 19, 2026

Copy link
Copy Markdown
Member Author

Thanks — reopened from my fork as #821.

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