Skip to content

fix: harden desktop shell against untrusted webviews and supply chain - #269

Open
ggrace519 wants to merge 3 commits into
open-webui:mainfrom
ggrace519:feat/security-hardening
Open

ggrace519 wants to merge 3 commits into
open-webui:mainfrom
ggrace519:feat/security-hardening

Conversation

@ggrace519

Copy link
Copy Markdown

Description

Guest Open WebUI pages (including remote connections) could invoke the full privileged desktop API via window.electronAPI[requestData.type]. Remote webviews also received Open Terminal API keys. TLS verification was disabled on every Chromium session. Python, llama.cpp, and Hugging Face GGUF downloads were not checksummed. Linux always launched with --no-sandbox. Packaged Electron fuses were left at insecure defaults. macOS/Windows releases published unsigned fallbacks on codesign failure.

This PR allowlists guest IPC, scopes TLS exceptions to user-added connection origins, verifies downloaded artifacts, sandboxes shell windows, pins Electron to 39.8.10 (GHSA-h7rp-cf8h-j98x), keeps Cloudflare Access / SSO login inside the app, and fails closed on unsigned releases.

Production shell windows load app://renderer/… instead of file://. Dev (npm run dev) is unchanged.

Overlaps (maintainers may want to close or rebase):

Fork-only docs (CLAUDE.md, DECISIONS.md, develop-branch model) are not in this PR.

Security

  • Guest send() allowlist: token:update, app:info, app:data, window:isFocused
  • will-attach-webview forces sandbox / contextIsolation / no Node
  • Terminal/OpenAI events only to the local-connection webview
  • TLS default-verify; exceptions only for configured connection origins + localhost
  • openExternal is http:/https:/mailto: only
  • HF paths confined; GGUF SHA-256 from Hub LFS (?blobs=true)
  • Python / llama.cpp downloads hashed; llama.cpp “latest” picks a release that actually has binaries
  • Child env blocklist; llama --host/--port/--models-dir always from the desktop
  • Linux --no-sandbox only for AppImage/snap/Flatpak/unpackaged/ELECTRON_DISABLE_SANDBOX=1
  • Electron fuses at pack time; shell sandbox: true; drop @electron-toolkit/preload window.electron

Fixes

  • Access/SSO stays in the webview (session cookies land; UI loads after callback)
  • Tray Quit actually exits
  • Guest no longer crashes on app:data (null instead of {} — Open WebUI +layout.svelte does not import appData)
  • Quit waits for child processes

Infrastructure

  • npm test (23 node:test cases on the security helpers)
  • CI: typecheck, tests, eslint on src/main + preload

Related Issues

Related to #175, #165. Does not close those if #218 is the intended path for OAuth host allowlisting.

Verification

npm test          # 23 pass
npm run lint:main # exit 0
npx tsc --noEmit -p tsconfig.node.json --composite false

Contributor License Agreement

@ggrace519
ggrace519 marked this pull request as draft September 6, 2026 13:27
Guest Open WebUI pages could invoke the full privileged desktop API.
Remote connections received Open Terminal keys. TLS was disabled
globally. Downloads of Python, llama.cpp, and GGUF weights were not
checksummed. This allowlists guest IPC, scopes TLS exceptions, verifies
artifacts, sandboxes shell windows, pins Electron 39.8.10, and keeps
Access/SSO login inside the app.

Co-authored-by: Grok 4.6 <grok@x.ai>
@ggrace519
ggrace519 force-pushed the feat/security-hardening branch from 634f6c0 to f91d995 Compare September 6, 2026 13:36
@ggrace519
ggrace519 marked this pull request as ready for review September 6, 2026 13:40
ggrace519 and others added 2 commits September 6, 2026 10:10
Windows node-pty throws "Cannot resize a pty that has already exited"
from the main process (Linux: ioctl EBADF). That uncaught exception
killed the whole app when the console tab resized during a server
restart.

Closes open-webui#255

Co-authored-by: Grok 4.6 <grok@x.ai>
Spawn cmd.exe instead of sh so the helper is exercised against real
conpty, tear the agent down so node:test can exit, and compare
confinedModelPath with path.resolve so the suite is not POSIX-only.

Co-Authored-By: Grok 4.6 <grok@x.ai>
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