Skip to content

fix(controlplane): close jul 20-21 vulnerability audit findings#2749

Merged
mekilis merged 7 commits into
mainfrom
smart/pde-800-vuln-oneshot-jul21
Jul 21, 2026
Merged

fix(controlplane): close jul 20-21 vulnerability audit findings#2749
mekilis merged 7 commits into
mainfrom
smart/pde-800-vuln-oneshot-jul21

Conversation

@mekilis

@mekilis mekilis commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Harden API and portal authorization: personal API key listing is scoped to the caller, portal auth-token refresh requires project manage, portal tokens cannot create broadcast/fanout/dynamic events, and bulk onboard / OpenAPI import require project manage for JWT callers.
  • Reduce credential and redirect exposure: portal link endpoints_metadata no longer includes signing secrets or soft-deleted endpoints; cloud billing checkout hosts are canonicalized before use.
  • Close remaining gates: OpenAPI import rejects external $ref fetches, pub/sub transforms honor the Transformations license, and email verification tokens are cleared after successful verify.

Test plan

  • CI lint and unit tests
  • Confirm dashboard personal API keys list still works
  • Confirm portal link responses omit secrets in endpoints_metadata
  • Confirm OpenAPI import still works for specs without remote $refs

Note

High Risk
Touches authentication, authorization, API key listing, portal credential exposure, billing redirect hosts, and OpenAPI import—security-critical paths where regressions could block legitimate users or leave holes if checks are wrong.

Overview
This PR hardens authorization and closes several credential/exposure gaps from a security audit.

API authorization: A shared rejectPortalLinkToken helper returns 401 for portal-link credentials on project-wide mutations—broadcast, fanout, and dynamic events; bulk onboard; OpenAPI import; and portal auth-token refresh. Bulk onboard and OpenAPI import also require project manage for JWT/PAT callers. Portal token refresh now requires project manage (not view alone). The dashboard GetAPIKeys route always scopes to the authenticated user’s personal keys and rejects other keyType values, fixing a case where an empty filter could list every key on the instance.

Data exposure: Portal link SQL no longer embeds endpoint signing secrets in endpoints_metadata, excludes soft-deleted endpoints from joins and counts, and tests assert secrets stay out of responses. Cloud billing onboard/upgrade checkout flows canonicalize host via validatePlanAndHost before calling billing.

Other gates: OpenAPI import disables external $ref resolution (SSRF); pub/sub body/header transforms run only when the Transformations license is enabled; successful email verification clears the verification token and expiry.

Reviewed by Cursor Bugbot for commit 72cbe46. Bugbot is set up for automated code reviews on this repo. Configure here.

mekilis added 5 commits July 21, 2026 11:25
scope GetAPIKeys to the caller's personal keys, require project manage to
refresh portal auth tokens, block portal tokens on broadcast/fanout/dynamic,
require manage for bulk onboard and openapi import, and canonicalize cloud
billing checkout hosts.
…l metadata

endpoints_metadata no longer embeds signing secrets, and soft-deleted
endpoints are excluded from joins and owner counts.
disable IsExternalRefsAllowed so import cannot fetch remote \$ref urls.
fail closed with a unit test for an external https ref.
match process_event_creation so unlicensed instances use the raw payload
instead of running transform functions on broker ingest.
…rify

prevents replaying a captured verification token until its previous ttl.
@linear

linear Bot commented Jul 21, 2026

Copy link
Copy Markdown

PDE-800

Comment thread api/handlers/portal_link.go
Comment thread internal/portal_links/queries.sql
…t counts

reject portal tokens on refresh_token so they cannot mint another link's
auth_key, and count only non-deleted endpoints in the empty-owner_id branch.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ed4c0fb. Configure here.

Comment thread api/handlers/onboard.go
…mport

requireJWTProjectManage skips portal credentials; these handlers have no
owner scoping, so portal callers must fail closed before the manage gate.
@mekilis
mekilis merged commit 7bee300 into main Jul 21, 2026
35 checks passed
@mekilis
mekilis deleted the smart/pde-800-vuln-oneshot-jul21 branch July 21, 2026 11:06
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.

1 participant