Skip to content

fix: close unauthenticated Pub/Sub event injection (CVSS 9.8)#64

Open
yuvalk wants to merge 5 commits intoRHEcosystemAppEng:mainfrom
yuvalk:CTF
Open

fix: close unauthenticated Pub/Sub event injection (CVSS 9.8)#64
yuvalk wants to merge 5 commits intoRHEcosystemAppEng:mainfrom
yuvalk:CTF

Conversation

@yuvalk
Copy link
Copy Markdown
Collaborator

@yuvalk yuvalk commented Mar 30, 2026

Summary

  • Split hybrid /dcr endpoint into /dcr (DCR only) and /pubsub (Pub/Sub with Google OIDC verification), preventing forged marketplace events
  • Remove blanket /marketplace/* auth bypass (PUBLIC_PREFIXES) from middleware — only /marketplace/pubsub remains public (has its own OIDC auth)
  • Add PUBSUB_AUDIENCE setting for OIDC audience verification, with a production warning when unset in Cloud Run
  • 13 new security tests covering OIDC verification, endpoint separation, and middleware hardening

Vulnerability

A researcher identified a CVSS 9.8 attack chain: forge Pub/Sub events → create fake entitlements → register OAuth clients → bypass authentication entirely. See report.txt for full details.

How it's fixed

Attack Step Defense
1. Forge ENTITLEMENT_ACTIVE via /dcr /dcr rejects Pub/Sub payloads (400); /pubsub requires Google-signed OIDC token
2. Register OAuth client without auth Blanket /marketplace/* bypass removed; DCR requires valid software_statement JWT
3. Authenticate to Agent API Red Hat SSO validation chain unchanged and intact

Test plan

  • 13 new tests in test_pubsub_auth.py pass
  • Existing Pub/Sub tests updated to use /pubsub with mocked OIDC
  • Full test suite: 207 passed, 0 failed
  • Lint clean (ruff)
  • Deploy to staging and verify Pub/Sub push subscription still delivers events with OIDC configured
  • Verify DCR flow still works end-to-end with Gemini Enterprise

🤖 Generated with Claude Code

yuvalk and others added 4 commits March 30, 2026 03:02
PUBLIC_PREFIXES allowed any /marketplace/* path to skip authentication.
This was overly permissive — only /marketplace/pubsub needs to be public
(it has its own Google OIDC verification). The specific path was already
in PUBLIC_PATHS, making the prefix redundant and dangerous.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The hybrid /dcr endpoint accepted both DCR and Pub/Sub requests without
verifying Pub/Sub message authenticity, enabling forged marketplace
events. Split into /dcr (DCR only) and /pubsub (Google OIDC-verified).

- /dcr now rejects requests without software_statement (400)
- /pubsub verifies Google OIDC tokens via google.oauth2.id_token before
  processing any event, rejecting unauthenticated requests (401)
- Audience verification is configurable via PUBSUB_AUDIENCE setting

Closes the unauthenticated marketplace event injection vulnerability
(CVSS 9.8) that allowed a full authentication bypass chain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add pubsub_audience config for OIDC audience verification on Pub/Sub
tokens. Warn at startup if unset in Cloud Run (K_SERVICE present) since
tokens without audience binding could be reused across services.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 13 new tests in test_pubsub_auth.py covering OIDC verification,
  endpoint separation, and middleware hardening
- Update existing Pub/Sub tests in test_dcr.py to use /pubsub endpoint
  with mocked Google OIDC token verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
suppressing since this is an external function that cannot be modified

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@luis5tb
Copy link
Copy Markdown
Collaborator

luis5tb commented Mar 30, 2026

The PR is missing the new configuration on the pubsub topic to send request to the pubsub endpoint instead of dcr

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.

2 participants