32 Commits

Author SHA1 Message Date
UNITRONIX 0bfecddd00 fix(docker): sync bootstrap admin password between Go and console (#385)
Fresh Docker installs without ADMIN_PASSWORD generated two different random
passwords: Go wrote /opt/rustdesk/.admin_credentials while the panel
authenticated against auth.db seeded by Node.js. Pre-bootstrap a shared
password in entrypoints before supervisord / server start.

Refs #385

Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
2026-08-24 15:08:35 +02:00
UNITRONIX 88d84e8c65 fix(keys): encode RustDesk config QR as reversed deploy string
Match rustdesk://config/ path to Copy deploy string so ServerConfig.decode accepts the QR (#368). Also align MFA otpauth URI with Go (issuer BetterDesk, 20-byte secret) and document Android 1.4.9 deep-link fallback in UI hints.

Refs #368

Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
2026-08-14 06:52:41 +02:00
UNITRONIX 0541ad15bc Prepare 3.4.0 stable release notes and fix default-admin bootstrap.
Populate CHANGELOG [Unreleased] with curated operator highlights since main 3.3.39, and remove illegal const password reassignment in ensureDefaultAdmin.
2026-07-24 21:33:17 +02:00
UNITRONIX 648a8d4f8a security(3.4): harden console and Go server for pre-release audit
Commit web-nodejs lockfile with tar override; CI uses npm ci and moderate npm audit.
Add LOG_LEVEL filtering and log redaction in Node console and Go server.
Validate WS tokens on bd-signal; require single-use token for remote-agent relay.
Limit active relay sessions per IP and block open enrollment without TLS.
2026-07-12 20:44:46 +02:00
UNITRONIX 382c082f21 fix(auth): add DB-backed RustDesk client sessions with sliding expiry
Fixes #242. Replace 24h JWT-only client tokens with configurable DB sessions (default 7 days, sliding renewal up to 30 days) and panel settings under Authentication -> RustDesk clients.
2026-07-09 20:00:53 +02:00
UNITRONIX c731c8b8ad fix(security): address CodeQL findings for release PR #185
Harden desktop-mode DOM rendering, branding sanitization, OIDC fetch
guards, API-key log redaction, tag-map allocation, and ws-register-test TLS.
2026-06-09 06:51:50 +02:00
UNITRONIX f346f891bc fix(security): phase-E shared Go API proxy, XSS hardening, audit clamp
Centralize path-segment validation in goApiProxy for fleet/commercialization/cross-platform routes while preserving RustDesk peer ID compatibility; sanitize panel JS output and cap audit Recent queries.
2026-06-09 03:22:14 +02:00
UNITRONIX 9b02f06465 fix(security): phase-C XSS hardening, path confinement, log redaction
Harden backup restore, theme/attachment paths, frontend escaping, and
sensitive logging without changing normal operator workflows.
2026-06-09 03:00:43 +02:00
UNITRONIX 6d7692ea6a fix(security): phase-A log redaction, font/transfer paths, CI permissions
Stop logging generated admin passwords, redact API login usernames,
confine font and file-transfer temp paths with safePath, and scope
GitHub Actions permissions in build.yml.
2026-06-09 02:42:56 +02:00
UNITRONIX c219f3be68 fix(security): patch CVE-2026-50575 and harden deps, SSRF, shell exec
Complete GHSA-3v82-3gf8-fxx8 WebSocket replay fix for soft-deleted peers,
bump vulnerable Go/Rust dependencies, and apply CodeQL-driven hardening
(OIDC URL validation, path confinement, execFileSync, rate limits).
2026-06-09 02:05:17 +02:00
UNITRONIX 50d1942f8c fix(auth): show username collision when LDAP matches local account (#148)
Add Go LDAP verify endpoint and probe it from the console when a local
user's password fails, so valid domain credentials return HTTP 409 with a
clear collision message instead of a misleading password mismatch. Includes
i18n for auth.username_collision across all console locales.
2026-06-07 00:32:03 +02:00
UNITRONIX bc98140959 fix(auth): block local/SSO username collision (#148)
Do not auto-convert an existing local account if Go authenticates the same
username via LDAP/OIDC. Treat it as a collision and require admin action,
preventing potential privilege confusion when names overlap.
2026-06-05 09:15:43 +02:00
UNITRONIX 3c4f1e2ec7 fix(console): sync auth_provider and LDAP login with Go (#148)
Repair the Node.js panel auth path so LDAP/OIDC users get the correct
provider and role from Go: forward authProvider in the database facade,
export syncUserFromGo, enforce provider-bound login, use unusable hashes
for external accounts, block panel edits of IdP-managed users, and
reconcile provider/role via Go API on PostgreSQL.
2026-06-05 02:24:14 +02:00
UNITRONIX 207a7467d0 fix(update): preserve operator config and passwords on upgrade (#158)
Merge .env keys instead of replacing files, patch systemd/NSSM in place,
block panel updates when the server cannot be rebuilt, and stop routine
updates from syncing admin passwords from .env into auth.db/PostgreSQL.
2026-06-04 00:13:12 +02:00
UNITRONIX b703db5e5f fix(auth): sync LDAP/OIDC provider and role from Go to panel (#148)
Node now persists auth_provider on SSO provisioning and re-syncs role/provider after Go login success, including SQLite auth.db backfill. Go login returns auth_provider; LDAP group mapping accepts CN keys and newlines. Default agent build cache under dataDir to avoid EACCES.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 02:42:25 +02:00
UNITRONIX f4ecb7bfe5 fix(auth): delegate unknown-user logins to Go LDAP/OIDC (#148)
Issue #148 reporter @Kreol13 confirmed LDAP test connection works but
actual login fails with 'user not found in database'. Root cause: the
Node.js console only delegates unknown-user logins to the Go server when
BETTERDESK_AUTH_AUTOCREATE=true is set explicitly (security audit fix
H-01). When LDAP/OIDC is configured via the UI, that env var is not set,
so LDAP/OIDC users who don't have a local account are rejected before
Go gets a chance to authenticate them.

Go server:
- New public endpoint GET /api/auth/sso/status returning
  {ldap_enabled, oidc_enabled, any_enabled}.
- Restored missing POST /api/auth/oidc/exchange route registration and
  authMiddleware whitelist (regression from earlier OIDC hardening).

Node.js console:
- authService.getGoSSOStatus() — cached 60s lookup of Go SSO state.
- authenticate() now auto-provisions LDAP/OIDC-authenticated users when
  any SSO provider is enabled on Go, in addition to the existing
  BETTERDESK_AUTH_AUTOCREATE opt-in. Default role drops from 'admin' to
  'viewer' for safer first-login provisioning when Go does not return
  an explicit role mapping. Logs name which provider triggered
  provisioning for audit clarity.

The H-01 concern (compromised Go server auto-provisioning admins) is
mitigated because enabling LDAP/OIDC requires an admin with the
server.config permission to explicitly opt in via the Authentication
settings tab.

This commit was made possible thanks to Insolve.
2026-06-01 04:38:04 +02:00
UNITRONIX 0f161181f1 feat(installers): run services under unprivileged accounts by default
Privilege separation across all installers so the long-running services no longer run with full administrative rights:

betterdesk.sh: installer keeps root but systemd units now run as a dedicated unprivileged 'betterdesk' system account by default (auto-created via ensure_service_user). Added full systemd hardening for the Go server (NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, ReadWritePaths) and light hardening for the Node.js console. chown migrates existing root-owned data to the service account on update. Opt-out via --run-as-root / BETTERDESK_RUN_AS_ROOT=1; custom account via BETTERDESK_SERVICE_USER. Minimal mode covered too.

betterdesk.ps1: NSSM services now run under their per-service low-privilege virtual accounts (NT SERVICE\<service>) instead of LocalSystem, with scoped icacls grants on the install/data dirs (Set-ServiceLeastPrivilege helper). Applied to the Go server, Node.js console and minimal-mode service. Opt-out via -RunAsRoot / BETTERDESK_RUN_AS_ROOT=1.

Docker: verified already privilege-separated (supervisord drops both programs to user=betterdesk; multi-container images drop via su-exec).

Also bundles in-progress changes to the Go server API, Node.js console services and Docker compose/Dockerfiles.

This commit was made possible thanks to Insolve.
2026-05-31 00:35:28 +02:00
UNITRONIX 60bccb489a fix(auth): restore local-first login flow — fixes login lockout after SSO update
The SSO commit (188991d) changed authenticate() to delegate auth to the Go server first, falling back to local-only for admin roles in 'emergency mode'. This broke login for all users whose accounts exist only in auth.db (Node.js) but not in Go server's database — which is the default for ALL-IN-ONE installs. Go server returned 401 for unknown users, and the new code treated that as a hard rejection with no local fallback. Restored the original local-first flow: check auth.db first, verify password locally, use Go server only as a fallback when local password fails (LDAP/password change sync) or when user doesn't exist locally (opt-in auto-create).

This commit was made possible thanks to Insolve.
2026-05-29 02:49:21 +02:00
UNITRONIX 188991d91d feat(auth): add LDAP and OIDC/OAuth2 SSO authentication
Go server: auth/ldap.go (LDAP bind + group-to-role mapping), auth/oidc.go (OIDC provider with PKCE, discovery, token exchange), api/ldap_handlers.go (config CRUD + test connection), api/oidc_handlers.go (authorize/callback/exchange/status + config CRUD), auth_handlers.go (LDAP auth branch before local password check + PBKDF2 rehash on login), password.go (NeedsRehash helper), server.go (LDAP/OIDC route registration + Init methods), main.go (InitLDAP/InitOIDC calls). Node.js console: auth.routes.js (OIDC proxy routes with open-redirect sanitization), settings.routes.js (LDAP/OIDC config tabs), authService.js (LDAP/OIDC auth flows with emergency mode), betterdeskApi.js (6 new SSO API methods), middleware/auth.js (emergencyMode flag), login.ejs (SSO buttons), settings.ejs (LDAP/OIDC config panels), navbar.ejs (SSO indicator). i18n: ~90 SSO keys added to EN/PL/ZH.

This commit was made possible thanks to Insolve.
2026-05-29 02:29:10 +02:00
Knienartowicz 8da6f8c9fd security: fix 3 critical + 3 high findings from production audit
Critical:

- C-01: WebSocket Origin validation (CSWSH protection) via new middleware/wsOrigin.js, applied to wsRelay, chatRelay, remoteRelay, bdRelay, cdapTerminalProxy, cdapMediaProxy

- C-02: Remove Tauri Origin-based CSRF bypass in server.js; only /api/bd/* skipped

- C-03: Update vulnerable deps (express 4.21.2, multer 2.0.0, protobufjs 7.4.0, helmet 7.2.0, axios 1.9.0, cookie-parser 1.4.7, express-session 1.18.1)

High:

- H-01: Disable auto-create-local-user on login by default; opt-in via BETTERDESK_AUTH_AUTOCREATE=true (does not affect ensureDefaultAdmin fresh-install bootstrap)

- H-02: Bearer-only auth for /api/bd/*; session cookie fallback removed; tokens redacted in logs

- H-05: Replace custom PBKDF2 with golang.org/x/crypto/pbkdf2; 600k iterations; new format pbkdf2-sha256\\\ with backward-compat for legacy salt:hash

Backward compatibility: legacy password hashes still verify; CSRF tokens still obtainable via csrfTokenProvider; fresh-install admin bootstrap (.admin_credentials flow) unchanged.

Audit report: docs/security/AUDIT_PRODUCTION_2026-04-10.md

This commit was made possible thanks to Insolve.
2026-05-26 13:35:12 +02:00
UNITRONIX c5970657e7 feat(i18n): expose all panel languages in selector
Render language choices dynamically from loaded locale files instead of hardcoding EN/PL. Add selectors on the navbar, login screen, and desktop login screen so users can choose a language before or after authentication.

Persist the selected language in the browser via cookie/localStorage and on authenticated accounts via users.preferred_language. Merge client translations with the default locale fallback so incomplete language files do not surface raw keys in the UI.
2026-05-03 02:02:15 +02:00
UNITRONIX 89e4e0a592 Refactor routes, relay, auth & chat integrations
Several cross-cutting fixes and refactors:

- API routing: Consolidated multiple org policy PUT endpoints into a single parameterized route (/api/org/{id}/policy/{category}) to simplify handlers (api/server.go).
- Relay/LAN handling: Prefer server LAN IP for LAN relay addresses (with proper port detection from configured relay), added strconv import and fallback to configured relay when LAN IP unknown; improves reliability with NAT hairpin issues (signal/handler.go).
- Web security: Allow inline event handlers (scriptSrcAttr: 'unsafe-inline') while still requiring nonced <script> tags for scripts used by admin pages (web-nodejs/middleware/security.js).
- CSRF: Include x-csrf-token header when POSTing language fix requests from the UI (web-nodejs/public/js/languages.js).
- Admin roles: Broaden admin checks to accept multiple admin role names via ADMIN_ROLES and update requireAdmin and RustDesk payload is_admin logic (web-nodejs/routes/rustdesk-api.routes.js).
- Admin credentials & startup resilience: authService now searches additional candidate dirs (config.dataDir, extra Windows/RustDesk paths, /app/data in Docker), skips empty candidates, and increases retries/delays when waiting for .admin_credentials (web-nodejs/services/authService.js).
- Chat API paths: Updated chat-related API calls to use /chat/* (instead of /api/chat/*) across persistence, history, contacts, groups, read and other operations (web-nodejs/services/chatRelay.js).

These changes improve compatibility (LAN relay, admin detection), robustness (longer retries, Docker/Windows path checks), and frontend behavior (CSRF token, inline handlers, updated chat endpoints).
2026-04-12 19:28:16 +02:00
UNITRONIX 7307388015 Improve migrations, LAN detection, auth & UI logs
DB: Use current_schema() when checking columns for deferred index creation and add exception handling to skip index creation if column is absent (avoids cross-schema false positives and race errors).
Signal: Harden isSameNetwork by normalizing IPv4, handling mapped addresses, adding detailed debug logs for loopback/private/subnet checks, and logging LAN detection failures in the RequestRelay handler.
Auth/API: Add tighter debug logging and trimming for /api/login (redacting passwords), and reject empty/invalid usernames early in authenticate() to address Issue #104.
UI: Add save button feedback (spinner, disable/restore), extra logging and error handling when saving org settings, and make logo image URL input editable by removing readonly.
2026-04-11 19:31:07 +02:00
UNITRONIX 45e5fda9d0 Implement RBAC v52, org scoping and assorted fixes
Adds a full Phase-52 RBAC implementation and multiple server/frontend fixes. Key changes: new auth/permissions.go with 28 granular permissions and DefaultRolePermissions, expanded 7-role hierarchy and helpers in auth/roles.go, JWT org context and GenerateOrgToken, requirePermission/requireOrgMembership middlewares (Go + Node.js), DB schema & adapter changes for role_permissions and is_server_admin, org role boundary checks and peer org scoping, and guards for last-admin demotion and self-demotion. Also: TCP EOF/connection-reset log filtering in signal/relay servers, improved startup banner port display, KEYS_PATH auto-detect warning, CSS hover/transition layout fixes, admin password race mitigation, ID-change ghost peer cleanup, added Tauri ACL schema files, and a new RBAC_PHASE52.md doc. Misc: numerous web-nodejs i18n, CSS, JS and route updates and an updated .github/copilot-instructions.md timestamp/summary.
2026-04-10 23:40:55 +02:00
UNITRONIX e8cb35b652 fix: read .admin_credentials on startup when DEFAULT_ADMIN_PASSWORD unset (Issue #88)
- ensureDefaultAdmin() now reads Go server's .admin_credentials file as
  fallback when DEFAULT_ADMIN_PASSWORD env var is not set
- Searches multiple candidate dirs: keysPath, keysPath/data, /opt/betterdesk,
  /opt/betterdesk/data, /opt/rustdesk, /opt/rustdesk/data
- Parses 'Admin Password: <value>' line from the file
- Fixes password mismatch on manual installs without ALL-IN-ONE scripts
- Existing installs with .env DEFAULT_ADMIN_PASSWORD are unaffected (env wins)
2026-04-07 19:37:05 +02:00
UNITRONIX f3ad154e7a Force admin password update and CSRF fixes
Ensure freshly generated admin passwords are actually applied on reinstall and make CSRF handling more robust. Install scripts (Docker, POSH, sh) now remove stale auth.db from the console_data/data volume or data dir and create a .force_password_update sentinel (Docker also sets FORCE_PASSWORD_UPDATE=true) so the Node.js console will force-update the admin password. web-nodejs/services/authService.js adds checkForcePasswordUpdate() (env var or sentinel) and will forcibly update the admin bcrypt hash when requested; sentinel files are removed after detection. CSRF middleware now only generates tokens for safe methods (GET/HEAD/OPTIONS), avoids interfering with state-changing requests, and clears corrupt cookies using consistent options (httpOnly, sameSite: 'lax', secure based on config) to prevent spurious 403s. server.js mounts rustdeskApiRoutes before CSRF so bearer-token desktop clients are not blocked by cookie-based CSRF. Also unified the health check path from /api/health to /health in diagnostics checks and added required fs/path imports.

Co-Authored-By: MrBrodacz - Design <215021251+MrBrodacz2025@users.noreply.github.com>
Co-Authored-By: boruto79 <176351662+boruto79@users.noreply.github.com>
2026-03-05 22:42:14 +01:00
UNITRONIX edba7c5da6 Improve password reset, auth logging, and i18n
Rework password reset flow and diagnostics: change reset-password.js argument order (password first, optional username) and update Docker/CLI scripts to call it accordingly; persist DEFAULT_ADMIN_PASSWORD to .env and restart betterdesk-console after resets to avoid overwrites. Add translations for an "invalid_credentials" message across supported locales. Harden reset-password.js with a bcrypt self-test, log hash info, and add additional data directory candidates. Enhance authService with detailed auth/logging (hash type, failures/success), safer admin-hash migration logic (avoid overwriting if admin has logged in), and self-tests when creating/updating admin password hashes to detect/retry corrupted hashes.

Co-Authored-By: MrBrodacz - Design <215021251+MrBrodacz2025@users.noreply.github.com>
Co-Authored-By: boruto79 <176351662+boruto79@users.noreply.github.com>
2026-03-05 00:55:58 +01:00
UNITRONIX aa9424845a Support Postgres, API key sync, and auth migration
Add PostgreSQL support for the web console password reset and install scripts, and improve cross-language auth handling.

Key changes:
- Introduce a unified reset-password.js that supports SQLite and PostgreSQL (reads DB_TYPE / DATABASE_URL) and make shell/PowerShell/Docker helpers prefer it with fallbacks.
- Update betterdesk-server to load an API key from API_KEY or .api_key (key/db dirs) and sync it into the database so Go server and Node console share the same key.
- Adjust docker-compose default command to run the all-in-one mode and point at the bundled DB/key paths.
- Improve dashboard health checks to avoid raw TCP probes in single-binary BetterDesk mode and derive signal/relay status from the API health; allow /api/currentUser to accept POST as well as GET.
- Enhance authService to recognize Go-style PBKDF2 hashes, verify them, auto-migrate verified PBKDF2 hashes to bcrypt, and migrate default admin if needed.

These changes improve interoperability between the Go server and Node console (shared API key and DB modes), add Postgres support for admin tooling, and provide a smooth auth migration path from the Go server's hashing scheme to bcrypt.

Co-Authored-By: MrBrodacz - Design <215021251+MrBrodacz2025@users.noreply.github.com>
2026-03-05 00:21:56 +01:00
UNITRONIX 00451634c7 Await DB operations in route handlers
Convert many Express route handlers and helper functions to async and await database calls (e.g. getAccessToken, touchAccessToken, getPeerById, getDevice, getPeerSysinfo, upsertPeerSysinfo, logAction, insertAudit*, getAll*/count* etc.). Also made identifyDevice and several route callbacks async, adjusted session.regenerate callback to use async logging, and replaced db.getDatabase() usage with db.getDb() where applicable. These changes ensure DB operations complete before responding and reduce race conditions/unhandled-promise behavior across numerous route files (activity, auth, automation, bd-api, devices, folders, i18n, inventory, registration, remote, rustdesk-api, and related route handlers).

Co-Authored-By: Charles Olivier Savignac <1275666+sircharlo@users.noreply.github.com>
2026-03-03 22:57:10 +01:00
UNITRONIX e855f5786d Add Go server and security audit; update web console
Add a new betterdesk-server Go codebase (server, api, auth, db, relay, signal, metrics, audit, ratelimit, proto, tools, tests) and related deployment/migration scripts. Add a comprehensive SECURITY_AUDIT_2026-03-01 report and .gitattributes; update copilot-instructions (ALL-IN-ONE v2.4.0), README, VERSION, Dockerfiles, scripts, docker-compose and entrypoint. Large updates to web-nodejs (translations, routes, services, frontend assets and middleware) and numerous new utilities; remove legacy Flask web files and archive hbbs-patch-v2 artifacts. Prepares repository for PostgreSQL support, DB migration tooling and the new Go server as the production backend.
2026-03-02 00:43:04 +01:00
UNITRONIX 12d195ff78 Release v2.3.0: Node.js console & security
Bump to v2.3.0 and switch to Node.js web console as the primary console (Flask deprecated). Add comprehensive security and feature updates: CSRF protection, session-fixation prevention, timing-safe auth, WebSocket auth, TOTP 2FA, operator/admin roles, address-book sync, desktop connect (URI handler), and SSL certificate configuration in installers. Introduce a dedicated RustDesk Client API (WAN port 21121) and related web-nodejs middleware, routes, views, protos, and client JS (rdclient) plus vendor libs. Add developer tooling and scripts (dev_modules), update hbbs-patch-v2 Rust sources, README and changelog/docs, and ignore Node.js artifacts in .gitignore.
2026-02-22 03:44:00 +01:00
UNITRONIX 32e29723e4 Add Node.js web console and update to v2.2.0
Introduce a new Node.js-based web console (Express + EJS + better-sqlite3) under web-nodejs/ and add installer support to choose between Node.js and the legacy Flask console. Update interactive ALL-IN-ONE installers (betterdesk.sh, betterdesk.ps1) with flags/options for --nodejs/--flask, automatic Node.js installation, migration logic, enhanced service handling and diagnostics. Bump VERSION to 2.2.0 and update README and project docs (.github/copilot-instructions.md) to reflect the new console, usage examples, and Docker/docs changes. Many new web-nodejs files and supporting middleware/services/routes/views/static assets were added to support the new console.
2026-02-17 10:59:46 +01:00