Skip to content

fix(googlechat): validate sub claim for Chat issuer tokens to prevent auth bypass - #3

Open
cubic-dev-ai[bot] wants to merge 1 commit into
mainfrom
fix/googlechat-auth-principal-validation
Open

fix(googlechat): validate sub claim for Chat issuer tokens to prevent auth bypass#3
cubic-dev-ai[bot] wants to merge 1 commit into
mainfrom
fix/googlechat-auth-principal-validation

Conversation

@cubic-dev-ai

@cubic-dev-ai cubic-dev-ai Bot commented Mar 26, 2026

Copy link
Copy Markdown

Summary

  • Security fix: The Google Chat webhook app-url token verification accepted tokens from any Google Chat app, not just the configured one. When email === CHAT_ISSUER, the function returned { ok: true } immediately without checking the sub claim (Project Number/App ID).
  • An attacker could create their own Google Chat app, point its webhook URL at the victim's OpenClaw instance, and have Google sign a valid token with the victim's URL as the aud. The token would pass verification because only aud and email were checked.
  • Now requires the sub claim to match the configured appPrincipal for all token types (both standard Chat issuer and Add-on issuer), not only Add-on tokens.
  • Renamed param expectedAddOnPrincipalexpectedPrincipal to reflect its broader scope.

Changes

  • extensions/googlechat/src/auth.ts — Unified principal validation: check sub claim against expectedPrincipal for both Chat issuer and Add-on issuer tokens before returning ok: true.
  • extensions/googlechat/src/monitor-webhook.ts — Updated call sites to use renamed expectedPrincipal param.
  • extensions/googlechat/src/targets.test.ts — Added tests for Chat issuer principal validation (match, missing, mismatch); updated existing Add-on tests for renamed param and error messages.
  • extensions/googlechat/src/monitor-webhook.test.ts — Updated assertion to use renamed param.

Test plan

  • pnpm test -- extensions/googlechat/src/targets.test.ts — 19 tests pass (includes 3 new Chat issuer principal validation tests)
  • pnpm test -- extensions/googlechat/src/monitor-webhook.test.ts — 2 tests pass
  • pnpm test -- extensions/googlechat/src/monitor.webhook-routing.test.ts — 5 tests pass
  • pnpm check — lint/format/type-check all pass

Breaking change note

Deployments using audienceType: "app-url" must now configure appPrincipal (the GCP Project Number) for their Google Chat account. Without it, webhook verification will reject all incoming tokens with "missing principal binding (appPrincipal config required)".

🤖 Generated with Claude Code

… auth bypass

The app-url token verification returned ok immediately for the Chat
issuer (chat@system.gserviceaccount.com) without checking the sub
claim. This allowed tokens from any Google Chat app to authenticate,
since Google signs them with the victim's webhook URL as the audience.

Require the sub claim (Project Number/App ID) to match the configured
appPrincipal for all token types, not only Add-on tokens. Rename the
param from expectedAddOnPrincipal to expectedPrincipal to reflect its
broader scope.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Requires human review: This PR modifies core authentication logic to fix a security vulnerability and introduces a breaking change, requiring human oversight to verify the fix and its impact.

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.

0 participants