GHSA-9pg3-25fq-p6cc
MEDIUMGHSA-9pg3-25fq-p6cc is a medium-severity (CVSS 5.5) CWE-598 vulnerability in github.com/juev/nebula-mesh. O3 Security confirms whether GHSA-9pg3-25fq-p6cc is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.
nebula-mesh: Newly-minted operator API key exposed in redirect URL (Referer, history, proxy logs)
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-9pg3-25fq-p6cc plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 368,770 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
github.com/juev/nebula-meshReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
internal/web/operators.go:251 — after handleOperatorCreateAPIKey mints a fresh 32-byte bearer token, the redirect points the operator's browser at:
/ui/operators/<id>?new_key=<raw-token>&key_name=<name>
The raw API key ends up:
- in the browser's URL history
- in the
Refererheader on every cross-origin asset the detail page loads (any third-party SVG/CSS/JS resource the layout pulls in) - in any reverse-proxy or load-balancer access log on the path (nginx default
combinedlog captures the query string) - in any structured log sink the operator's local browser-history backup tool ships out
Authorization: Bearer <token> headers go through the same hops without these problems because access logs typically don't capture request headers and the browser doesn't replay headers cross-origin.
Same handler also appends name (r.FormValue("name")) to the query string without url.QueryEscape, so an & in the operator-supplied key name corrupts query parsing and a \r\n in older proxies could split response headers.
Affected
All released versions up to v0.3.1.
Reproducer
As admin, create an API key via /ui/operators/<id>/api-keys (form POST). The 303 Location header carries the raw token in the query string. Open browser DevTools → Network → response headers; or check the reverse-proxy access log; or check the operator-detail page's Referer-emitting fetches.
Suggested fix
Stash the raw key in a one-shot server-side flash storage (e.g., a row in operator_sessions keyed by session token, with a one_shot_token column and consumed_at) or in a short-lived signed cookie. Render the key once inline on the detail page after the redirect, and clear the storage on render. Pattern mirrors the recovery-codes display in the TOTP flow.
If the flash-storage refactor is too invasive, the minimal fix is to render the key inline via a POST → 200 OK with HTML (no redirect), losing the post-redirect-get idiom but eliminating the URL exposure.
Also fix name query encoding with url.QueryEscape regardless of which fix shape lands.
CVSS estimate
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N — 5.5 (medium). AV:L because realistic exploit requires log-read access on shared infrastructure (proxy, CDN, browser-history backup) the operator's session touches.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/juev/nebula-mesh | all versions | 0.3.2 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/juev/nebula-mesh. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update github.com/juev/nebula-mesh to 0.3.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-9pg3-25fq-p6cc is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-9pg3-25fq-p6cc is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-9pg3-25fq-p6cc. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-9pg3-25fq-p6cc in your dependencies?
O3 detects GHSA-9pg3-25fq-p6cc across Go dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.