GHSA-q6xx-5vr8-p898 - Nezha WebSocket stream ownership bypass
Nezha 1.14.13-1.14.14 and 2.0.0-2.0.9 authenticated WebSocket terminal
and file-manager sessions only by the presence of a live stream UUID. The
stream UUID was not bound to the user who created it, so another authenticated
dashboard user who obtained the UUID could attach to the terminal or file
manager for a server they did not own.
This is a cross-tenant authorization bypass with shell and filesystem impact.
When to use it
- A repository deploys, vendors, forks, builds, or packages affected Nezha versions.
- Multiple users or tenants can access dashboard terminal or file-manager features.
- Stream UUIDs may appear in logs, telemetry, browser history, referrers, or support bundles.
- You need a bounded PR or triage note that binds WebSocket streams to owners before attach, close, or mutation.
Inputs
- Go modules, forks, images, manifests, SBOMs, deployment artifacts, and Nezha version evidence.
- Stream creation/attach/close code, terminal and file-manager routes, user and server ownership model, and logging/telemetry paths.
- Available Go authz tests, build, image build, deployment render, SBOM, and dependency/security scan commands.
Affected versions
- Vulnerable:
github.com/nezhahq/nezha >=1.14.13, <=1.14.14 - Vulnerable:
github.com/nezhahq/nezha >=2.0.0, <=2.0.9 - Fixed:
2.0.10+for the 2.x line - Affected surface:
/ws/terminal/:id,/ws/file/:id, and stream allocation/attachment logic
Indicator-of-exposure
- The repository deploys, vendors, forks, or builds affected Nezha versions.
- Multiple dashboard users or tenants can access the same deployment.
- Web terminal or file manager features are enabled.
- Stream UUIDs can appear in access logs, telemetry, browser history, referrers, support bundles, or shared observability tools.
Quick checks:
rg -n "nezhahq/nezha|CreateStream|GetStream|CloseStream|terminalStream|fmStream|/ws/terminal|/ws/file|IsStreamAuthorizedForUser" .
go list -m all | rg "nezhahq/nezha"
Windows:
rg -n "nezhahq/nezha|CreateStream|GetStream|CloseStream|terminalStream|fmStream|/ws/terminal|/ws/file|IsStreamAuthorizedForUser" .
go list -m all | rg "nezhahq/nezha"
Remediation strategy
- Upgrade Nezha 2.x deployments to
2.0.10+. - If operating the 1.14 line, backport the creator-binding fix or retire the unsupported line.
- Store creator user ID or equivalent owner context when streams are created.
- Authorize stream attachment against the caller before WebSocket upgrade and before closing or mutating the existing stream.
- Reduce UUID leakage from logs and telemetry.
The prompt
Model context: this prompt was generated by GPT 5.5 Extra High reasoning.
You are remediating GHSA-q6xx-5vr8-p898 in Nezha. WebSocket terminal and
file-manager streams are authorized only by UUID, enabling cross-tenant session
hijack. Produce exactly one output:
- A reviewer-ready PR/change request that upgrades Nezha, binds streams to
creators, adds regression tests, and documents operator cleanup, or
- TRIAGE.md if this repository does not control an affected Nezha runtime,
fork, image, or deployment.
## Rules
- Scope only GHSA-q6xx-5vr8-p898 and directly related stream ownership checks.
- Treat stream UUIDs, terminal output, file paths, server IDs, user IDs, and
access logs as sensitive.
- Do not connect to live terminal or file-manager sessions for validation.
- Do not auto-merge.
## Steps
1. Inventory every Nezha module, fork, image, manifest, SBOM, and deployment
artifact controlled by this repository.
2. Confirm whether any 1.x runtime resolves to `1.14.13-1.14.14` or any 2.x
runtime resolves to `2.0.0-2.0.9`.
3. Trace stream creation, terminal attach, file-manager attach, and stream
closure paths.
4. If this repository does not control an affected Nezha runtime, stop with
`TRIAGE.md` naming the owner and required action: upgrade to `2.0.10+` or
backport creator-bound stream authorization.
5. Upgrade 2.x deployments to `2.0.10+`, or backport the creator-binding fix
for maintained 1.x forks.
6. Bind each stream to creator user ID and server ownership context at creation.
7. Require authorization before WebSocket upgrade and before stream closure so
rejected attach attempts cannot disrupt legitimate sessions.
8. Add regression tests proving a low-privilege authenticated user cannot attach
to or close another user's terminal or file-manager stream.
9. Add a PR body section named `GHSA-q6xx operator actions` covering:
- Nezha versions before and after;
- whether terminal/file-manager features were enabled;
- where stream UUIDs may have been logged or exposed;
- session/log review and credential cleanup guidance;
- validation that passed.
10. Run available validation: `go test`, authz tests, build, image build,
deployment render, and dependency/security scans.
11. Use PR title:
`fix(sec): bind Nezha WebSocket streams to owners`.
## Stop conditions
- No affected Nezha runtime, fork, image, or deployment is controlled here.
- Verification would require attaching to live terminal or file-manager
sessions.
- The 1.x line cannot be fixed without a product support decision.
- Validation fails for unrelated pre-existing reasons; document those failures.
Verification - what the reviewer looks for
- Nezha 2.x deployments are
2.0.10+, and any 1.x fork has an equivalent creator-binding fix or is retired. - Stream attach and close operations verify the caller owns or may administer the stream.
- Tests cover terminal and file-manager WebSocket paths.
Output contract
- Reviewer-ready PR upgrading Nezha to
2.0.10+or backporting creator-bound stream authorization for maintained 1.x forks. - Regression tests proving unauthorized users cannot attach to or close another user’s terminal or file-manager stream.
- Operator notes for terminal/file-manager exposure, UUID logging, session/log review, and credential cleanup.
TRIAGE.mdwhen the affected runtime, fork, image, or deployment is not controlled by this repository.
Watch for
- Checking ownership after WebSocket upgrade instead of before it.
- Rejecting unauthorized attaches but still closing the legitimate stream.
- Logging full stream UUIDs in shared observability systems.
Related recipes
- CVE-2026-54329 Snipe-IT cross-tenant accessory injection
- Browser agent boundary
- CVE intelligence intake gate