Skip to content

fix(security): remediate Dependabot alerts #93, #94, #86 - #29

Merged
dizhaky merged 2 commits into
mainfrom
dan/DAN-sec-dependabot-93-94-86
Jun 24, 2026
Merged

fix(security): remediate Dependabot alerts #93, #94, #86#29
dizhaky merged 2 commits into
mainfrom
dan/DAN-sec-dependabot-93-94-86

Conversation

@dizhaky

@dizhaky dizhaky commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Remediates three open Dependabot security alerts that Dependabot's auto-fix did not raise PRs for.

Alerts addressed

Alert Severity Package Advisory Fix
#93 HIGH hermes-agent (WebSocket endpoints) GHSA-4pqm-j46f-795x / CVE-2026-53869 Code fix — Host/Origin validation on WS upgrades
#94 MEDIUM hermes-agent (same root cause) GHSA-4pqm-j46f-795x Same fix as #93
#86 MEDIUM js-yaml (npm, website) GHSA-h67p-54hq-rp68 Override to 4.2.0 + patch gray-matter

#93 / #94 — DNS rebinding via WebSocket endpoints (code fix, not a lockfile bump)

The advisory's "patched in 0.16.0" refers to the upstream PyPI hermes-agent semver. This repo is a fork of NousResearch/hermes-agent that pins its own version (0.14.0, source = editable ".") and uses CalVer tags — there is no 0.16.0 to regenerate uv.lock against, and the fork is ~1400 commits behind the upstream patched line (v2026.6.5), so it never received the fix. Regenerating the lock cannot resolve this — the actual remediation is porting the upstream code fix.

Root cause: FastAPI's @app.middleware("http") Host-header guard (already present in this fork for GHSA-ppp5-vxwm-4cf7) does not run on WebSocket routes. The four WS endpoints (/api/pty, /api/ws, /api/pub, /api/events) validated only the session token and the peer IP (loopback) — both of which a DNS-rebinding attacker satisfies (the browser's connection peer is 127.0.0.1 after the TTL flip).

Fix: ported the upstream guard as _ws_host_origin_is_allowed(), reusing this fork's existing _is_accepted_host() HTTP-layer helper, and call it in all four handlers before accept(). Non-browser clients (no Origin) and native app:///file:// origins stay allowed — the session token remains their auth boundary. Added TestWebSocketHostOriginGuard regression coverage.

#86 — js-yaml quadratic DoS (website)

The flagged js-yaml@3.14.2 is gray-matter's transitive dependency (@docusaurus/utils → gray-matter → js-yaml ^3). js-yaml 3.x has no patched release, and gray-matter 4.0.3 (latest) calls yaml.safeLoad/safeDump, both removed in js-yaml 4 — so an overrides bump alone breaks the Docusaurus build (verified).

Fix: force js-yaml@4.2.0 via overrides and patch gray-matter's default engine to yaml.load/yaml.dump (safe-by-default in v4, equivalent to the removed safeLoad) via patch-package (website/patches/gray-matter+4.0.3.patch, applied by a postinstall hook).

Verification

  • Python: pytest tests/hermes_cli/test_web_server_host_header.py tests/hermes_cli/test_web_server.py → 157 passed, including 5 new WS-guard tests. (3 pre-existing TestPtyWebSocket PTY-streaming failures are unrelated and also fail on main in this environment.)
  • Website: package-lock.json contains only js-yaml@4.2.0 (no 3.x); npm audit → 0 vulnerabilities; npm run build[SUCCESS] Generated static files for all locales.
  • Both commits are SSH-signed (-S).

Note: CODEOWNERS may require approval from both @dizhaky and @izhaky.

🤖 Generated with Claude Code

dizhaky and others added 2 commits June 24, 2026 15:40
…j46f-795x)

Dependabot alerts #93 (HIGH) and #94 (MEDIUM): DNS-rebinding bypass via the
dashboard WebSocket endpoints. FastAPI's @app.middleware("http") host-header
guard does not run on WebSocket routes, so /api/pty, /api/ws, /api/pub, and
/api/events accepted upgrades from any Host/Origin as long as the connection
peer was loopback — which a TTL-flipped attacker hostname satisfies.

Port the upstream fix (NousResearch/hermes-agent, patched in v2026.6.5):
add _ws_host_origin_is_allowed() reusing the existing _is_accepted_host
HTTP-layer defence, and call it in all four WS handlers before accept().
Non-browser clients (no Origin) and native app:// / file:// origins remain
allowed — the session token stays their auth boundary.

Adds regression coverage in TestWebSocketHostOriginGuard and sends a loopback
Host header in the sidecar-url WS test (now required by the guard).

Refs: GHSA-4pqm-j46f-795x, CVE-2026-53869

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-rp68)

Dependabot alert #86 (MEDIUM): quadratic-complexity DoS in js-yaml merge-key
handling, fixed in 4.2.0. The flagged copy was gray-matter's hard dependency
(Docusaurus -> @docusaurus/utils -> gray-matter -> js-yaml ^3, resolving to
3.14.2); js-yaml 3.x has no patched release.

gray-matter 4.0.3 is the latest release and calls yaml.safeLoad/safeDump,
both removed in js-yaml 4 — so an `overrides` bump alone breaks the docs
build. Force js-yaml to 4.2.0 via overrides AND patch gray-matter's default
engine to use yaml.load/yaml.dump (load is safe-by-default in v4, equivalent
to the removed safeLoad). Applied at install time via patch-package.

Verified: only js-yaml 4.2.0 remains in the lockfile, `npm audit` reports 0
vulnerabilities, and `npm run build` succeeds for all locales.

Refs: GHSA-h67p-54hq-rp68

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔎 Lint report: dan/DAN-sec-dependabot-93-94-86 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8650 on HEAD, 8650 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4568 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@dizhaky
dizhaky merged commit 96e54e7 into main Jun 24, 2026
31 checks passed
@dizhaky
dizhaky deleted the dan/DAN-sec-dependabot-93-94-86 branch June 24, 2026 19:49
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