CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-3fcr-jvgp-7f58: pytonapi has a Webhook Custom Path Authentication Bypass

highCVSS 7.5CVE-2026-54635
Webhook Custom Path Authentication Bypass in pytonapi Summary TonapiWebhookDispatcher in pytonapi 2.2.0 fails to validate the Authorization header when a webhook handler is registered with the documented path= argument. During setup(), bearer tokens are stored only under the default suffix paths (e.g., /hook/account-tx), but the custom path (e.g., /hook/custom) is never added to the token map. When an incoming request arrives at the custom path, self._tokens.get(path) returns None, causing the if expected_token is not None guard to evaluate to False and silently skip authentication entirely. An unauthenticated remote attacker can POST arbitrary forged payloads to the custom webhook endpoint and trigger victim-defined handlers with full integrity impact. Details The vulnerability is a fail-open authentication check in pytonapi/webhook/dispatcher.py. Token registration (setup) stores tokens only under default suffix paths: dispatcher.py lines 109-112 suffix = self.DEFAULT_SUFFIXES[event_type] local_path = self._path + suffix # e.g., "/hook/account-tx" webhook = await self._client.ensure(f"{self._url}{suffix}") self._tokens[local_path] = webhook.token # custom path is NEVER stored here Handler registration preserves the custom path in the handler tuple: dispatcher.py lines 339, 342 resolved_path = path or self._resolve_path(event_type) # -> "/hook/custom" self._handlers[event_type].append((account_filter, fn, resolved_path)) Path routing (_build_path_map) correctly maps the custom path to the event type: dispatcher.py line 182 return {handlers[0][2]: et for et, handlers in self._handlers.items() if handlers} -> {"/hook/custom": WebhookEventType.ACCOUNT_TX} Authentication check (fail-open): dispatcher.py lines 286-288 expected_token = self._tokens.get(path) # "/hook/custom" -> None if expected_token is not None and authorization != f"Bearer {expected_token}": raise TONAPIError("Invalid webhook token") # SKIPPED because expected_token is None Because expecte

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 7.5
Published
2026-07-28
Last updated
2026-07-28
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-3fcr-jvgp-7f58

Exploitation outlook

EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-54635coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories