Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources, documents or advisories need attention: 272/272 feeds/APIs · 469/469 docs · 7/9 advisories · checked 04:34 UTC Customize Public modeDiscuss ChangeIntel on Discord

9router: Mass assignment in PATCH /api/settings allows authenticated authorization downgrade

Exact source revision recorded 24 Oct 2026 13:17:17 UTC. It does not establish the source's current position. Latest evidence.

osv · GHSA-vmjq-hvgq-2wv4

Published

### Summary The `PATCH /api/settings` endpoint writes the entire request body to persistent settings without a field whitelist. An authenticated user can set security-critical fields that are not meant to be modifiable here — notably `requireLogin`. Setting `requireLogin: false` disables authentication for the whole application, exposing all protected routes (e.g. `/api/keys`, `/api/providers`) to unauthenticated access. ### Details Root cause is unfiltered mass assignment (CWE-915): - `src/app/api/settings/route.js` (PATCH handler) parses the body and passes it to `updateSettings(body)`, with special handling only for `newPassword` and `oidcClientSecret`. All other fields pass through. - `src/lib/db/repos/settingsRepo.js` — `updateSettings` does `next = { ...current, ...updates }`, so any key in the body overwrites stored settings, including `requireLogin`, `tunnelDashboardAccess`, `authMode`. - `src/dashboardGuard.js` — `isAuthenticated` returns `true` whenever `settings.requireLogin === false`, bypassing auth on all protected routes. This is distinct from CVE-2026-5842 (CWE-285, pre-auth bypass on `/api`, patched in 0.3.75). This finding requires a valid authenticated session and abuses input handling, not missing authentication. ### PoC Instance on `localhost:20128`, default password `123456`. 1. Authenticate, capture session: `POST /api/auth/login` body `{"password":"123456"}` → `200 {"success":true}` 2. Mass-assign with the authenticated session: `PATCH /api/settings` body `{"requireLogin":false}` → `200`, response confirms `"requireLogin":false` 3. Verify bypass with NO session/credentials: `GET /api/keys` → `200`, returns full API key list unauthenticated 4. Cleanup (authenticated): `PATCH /api/settings` body `{"requireLogin":true}` → `GET /api/keys` returns `401` again ### Impact Post-authentication mass assignment. Any authenticated user (including one using the default password) can disable authentication globally, then read all stored API keys and provider connection data without credentials, and toggle tunnel/dashboard exposure. Escalates to remote full compromise when chained with the default password `123456` on an instance exposed via tunnel (`tunnelDashboardAccess` defaults to `true`). ### Suggested fix Whitelist user-configurable fields in the PATCH handler; move security-critical fields (`requireLogin`, `tunnelDashboardAccess`, `authMode`) to a dedicated endpoint requiring re-authentication (current-password re-entry), mirroring the existing DB export/import re-auth flow.

Source published
23 Sep 2026 18:12:33 UTC
Source modified
23 Sep 2026 18:27:57 UTC
Observed here
24 Oct 2026 13:17:17 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V4 · CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N

Publisher rating · HIGH

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 27 Oct 04:34 UTC · 272 of 272 readable · 270 fully read · documentation 469/469 current