fix(security): use hmac.compare_digest for BlueBubbles webhook token to prevent timing attacks - #9219
fix(security): use hmac.compare_digest for BlueBubbles webhook token to prevent timing attacks#9219memosr wants to merge 1 commit into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing a real timing-sensitive webhook-auth path. Current main still uses token != self.password at gateway/platforms/bluebubbles.py:883, so the security premise is valid.
Problems
- The added
hmac.compare_digest(token or "", self.password or "")compares rawstrvalues. Python documents string operands as ASCII-only; the adapter acceptsBLUEBUBBLES_PASSWORDdirectly atgateway/platforms/bluebubbles.py:128, without ASCII validation. A non-ASCII password could therefore raise rather than return the existing 401 behavior. - No regression tests accompany this authentication change.
tests/gateway/test_bluebubbles.pycurrently lacks wrong-password, missing-credential, and comparator-invocation coverage.
Suggested changes
- Compare UTF-8 encoded operands so all configured string passwords are handled safely.
- Add focused auth tests for wrong/missing credentials and constant-time comparator use. The timeline's cross-referenced open duplicate #44025 already illustrates both pieces.
Automated hermes-sweeper review.
| @@ -770,7 +771,7 @@ async def _handle_webhook(self, request): | |||
| or request.headers.get("x-guid") | |||
There was a problem hiding this comment.
compare_digest only accepts ASCII str operands. This adapter accepts arbitrary BLUEBUBBLES_PASSWORD strings, so encode both operands to UTF-8 bytes here; otherwise a non-ASCII password can raise instead of returning the existing 401 response.
…to prevent timing attacks
bf7c7ec to
014bbde
Compare
|
Addressed both sweeper findings:
All 67 tests in the file pass. Rebased onto current main; still a single commit. |
|
looks mergeable The webhook authentication fix is correctly applied at the only BlueBubbles webhook entrypoint. It replaces the ordinary token inequality with hmac.compare_digest over UTF-8 bytes, preserves the early 401 rejection, and keeps valid and invalid non-ASCII credentials from raising. Focused regression tests cover missing, empty, wrong, correct, and non-ASCII credential cases; no residual authentication bypass was found. Review note: I used a run-owned local patch replay against current GitHub Security evidence:
Not checked:
Signed: GPT-5.6-luna-max in Codex |
What does this PR do?
gateway/platforms/bluebubbles.pyvalidated the webhook token usingPython's
!=operator:String inequality with
!=short-circuits at the first mismatchedcharacter. An attacker can measure response times to determine how
many leading characters of their guess match the real token,
eventually recovering it character by character (timing oracle attack).
Fix
Replaced with
hmac.compare_digest()which always takes the sametime regardless of where the strings differ:
The
or ""guards handleNonevalues safely sincehmac.compare_digest()requires string arguments.Type of Change
Checklist
hmacis Python standard library — no new dependencies