Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,22 @@
# Dockerfile once a release vendors brace-expansion >= 5.0.8, then remove
# this entry.
CVE-2026-14257

# CVE-2026-69152 (GHSA-rgw5-rvv9-x895) — brace-expansion 5.0.7 DoS via
# unbounded intermediate arrays (bypass of the CVE-2026-14257 mitigation).
# Same vendored copy inside the global npm@11.18.0 as above; fixed in 5.0.9
# (published 2026-07-30), which no npm release vendors yet (checked 11.19.0,
# 2026-08-18). Same non-exploitability rationale as CVE-2026-14257. See
# SECURITY.md → "CVE-2026-69152 (brace-expansion DoS bypass in bundled npm)".
CVE-2026-69152

# CVE-2026-69192 (GHSA-mwp4-54f8-5fhr) — ip-address 10.2.0 inconsistent
# leading-zero octet parsing (SSRF / trust-boundary bypass). Vendored inside
# the global npm@11.18.0 via socks-proxy-agent → socks → ip-address; only
# exercised when npm itself is configured to use a SOCKS proxy. The
# application never loads code from the global npm install and no
# attacker-controlled addresses reach it. Fixed in 10.3.1 (published
# 2026-07-25), not yet vendored by any npm release. See SECURITY.md →
# "CVE-2026-69192 (ip-address SSRF in bundled npm)". Remove both entries when
# the Dockerfile npm pin is bumped to a release vendoring the fixes.
CVE-2026-69192
100 changes: 100 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,106 @@ new-release quarantine (all published on or before 2026-07-14).

---

## August 2026 npm audit findings (socket.io-parser, nanoid, brace-expansion)

As of 2026-08-18, `npm audit --audit-level=high` reported three HIGH
advisories. All were remediated the same day under the CVE exception to the
14-day quarantine; each fix version was verified against its maintainer and
publish date before adoption.

### GHSA-2m8v-j782-fhvr (socket.io-parser zero-attachment memory exhaustion)

| Aspect | Status |
| ------------------ | ----------------------------------------------------------------------------- |
| Vulnerability type | Memory exhaustion via crafted binary packets declaring zero attachments |
| Affected versions | 4.0.0 – 4.2.6 |
| Our exposure | **Production** — `socket.io@4.8.3` → `socket.io-parser`; our own `overrides` pinned 4.2.6 |
| Status | **Remediated 2026-08-18** — override bumped to 4.2.7 (published 2026-07-15) |

This is the only production-path finding. Any WebSocket client able to reach
the Socket.IO endpoint could send the malformed packet, so it was treated as
directly exploitable. `socket.io`'s own `~4.2.4` range resolves to 4.2.7
naturally; the override is retained to make the floor explicit.

### GHSA-2v37-7h3g-55p8 (nanoid infinite loop with zero-size custom generator)

| Aspect | Status |
| ------------------ | ----------------------------------------------------------------------------- |
| Vulnerability type | Denial of Service — custom generators loop indefinitely when `size` is 0 |
| Affected versions | < 3.3.18 |
| Our exposure | Dev toolchain only — `vitest` → `vite` → `postcss` → `nanoid@3.3.16` |
| Status | **Remediated 2026-08-18** — new `overrides` pin `nanoid@3.3.18` (published 2026-08-07) |

Not present in the production install (`npm ci --omit=dev`) or the Docker
image. postcss's own floor (`^3.3.16`) is satisfied by the vulnerable
version, so an explicit override was required to force the bump.

### GHSA-rgw5-rvv9-x895 (brace-expansion DoS via unbounded intermediate arrays)

| Aspect | Status |
| ------------------ | ----------------------------------------------------------------------------- |
| Vulnerability type | Denial of Service — bypass of the CVE-2026-14257 mitigation |
| Affected versions | 4.0.0 – 5.0.8 |
| Our exposure | Dev toolchain only — `eslint-plugin-sonarjs` → `minimatch@10.2.6` → `brace-expansion@5.0.8` |
| Status | **Remediated 2026-08-18** — lockfile refreshed to 5.0.9 (published 2026-07-30) |

Same posture as GHSA-mh99-v99m-4gvg above: devDependency only, lint glob
patterns are first-party. No override needed — 5.0.9 sits inside minimatch's
existing `^5.0.8` range.

---

## Bundled-npm findings in the runtime image (Trivy, 2026-08-18)

Trivy's image scan (`docker-image-scan` CI job) began flagging two HIGH CVEs
on 2026-08-18. Both live under
`/usr/local/lib/node_modules/npm/node_modules/` — the global `npm@11.18.0`
pinned by the Dockerfile runtime stage — not in the application dependency
tree. As of 2026-08-18 no published npm release (latest checked: 11.19.0,
2026-07-29) vendors the fixed versions, so there is no upgrade path yet. Both
are suppressed in `.trivyignore` with the assessments below.

### CVE-2026-69152 (brace-expansion DoS bypass in bundled npm)

| Aspect | Status |
| ------------------ | ------------------------------------------------------------------------------ |
| Advisory | GHSA-rgw5-rvv9-x895 (published 2026-08-03) |
| Vulnerability type | Denial of Service via unbounded intermediate arrays (bypasses CVE-2026-14257 fix) |
| Affected versions | 4.0.0 – 5.0.8 (fixed in 5.0.9, published 2026-07-30) |
| Our exposure | brace-expansion 5.0.7 vendored inside the pinned global `npm@11.18.0` |
| Status | **Not exploitable** — same rationale as CVE-2026-14257 above |

The application's own copy (dev toolchain, via minimatch) was moved to 5.0.9
the same day — see the August 2026 npm audit section above. Only the bundled
npm copy remains, and the container never invokes npm on attacker-controlled
glob patterns.

### CVE-2026-69192 (ip-address SSRF in bundled npm)

| Aspect | Status |
| ------------------ | ------------------------------------------------------------------------------ |
| Advisory | GHSA-mwp4-54f8-5fhr (published 2026-08-03) |
| Vulnerability type | Inconsistent leading-zero octet parsing → SSRF / trust-boundary bypass |
| Affected versions | < 10.3.1 (fixed in 10.3.1, published 2026-07-25) |
| Our exposure | ip-address 10.2.0 vendored inside `npm@11.18.0` via `socks-proxy-agent` → `socks` |
| Status | **Not exploitable** — code path only runs when npm uses a SOCKS proxy |

**Why we are not affected:**

- `ip-address` is not a dependency of webssh2; it exists in the image solely
as npm's SOCKS proxy support. The application (`node dist/index.js`) never
loads code from `/usr/local/lib/node_modules/npm`.
- The only in-container npm use is the operator-run `npm run hostkeys:prod`,
which does not talk to a registry or proxy.
- `socks@2.8.9` declares `ip-address@^10.1.1`, so a future npm release that
refreshes its lockfile will pick up 10.3.1 automatically.

**Re-evaluate on each npm release:** bump the Dockerfile `npm@11.18.0` pin
once a release vendors brace-expansion >= 5.0.9 and ip-address >= 10.3.1,
then remove both `.trivyignore` entries (and CVE-2026-14257's).

---

## Shai-hulud 2.0 supply chain risk

As of 2026-01-27, automated checks for Shai-hulud 2.0 indicators of compromise (IoCs) found **no evidence of compromise** in this repository.
Expand Down
Loading
Loading