Theseus: wallet-imports and Hermes IPC only answer their own pages

wallet-imports-signer hands out raw seeds and WIFs while the vault is
open, and hermes-* sends and reads the user's Nostr messages; none of
these handlers checked who was asking. No preload exposes the
wallet-imports channels (add-ons use the vaultImports shim), so they
are now Settings-only like the password channels; the Hermes channels
answer only the Messages window.
This commit is contained in:
Local Dev 2026-10-04 04:22:41 +02:00
parent f214abaf1b
commit f823c042e3

14
main.js
View file

@ -872,7 +872,14 @@ const SETTINGS_ONLY = new Set([
"recheck-update", "remove-from-list", "set-engine-enabled", "set-engine-order",
"settings-open-panel", "settings-section", "tor-state",
"vault-pin-clear", "vault-pin-set", "vault-pin-status", "vault-pin-unlock",
// Raw seeds and WIFs. No page uses these (add-ons go through the
// vaultImports shim in main), but an unguarded handler is reachable by any
// renderer that gets code execution.
"wallet-imports-add", "wallet-imports-list", "wallet-imports-remove", "wallet-imports-signer",
]);
// Hermes (Nostr messaging) speaks as the user and reads their messages:
// only its own window may drive it.
const HERMES_ONLY = new Set(["hermes-status", "hermes-init", "hermes-can-use-vault", "hermes-close", "hermes-inbox", "hermes-send"]);
const SETTINGS_SHARED = new Set([
"add-engine", "addons-apply-staged", "addons-list-staged", "app-restart", "collision-state",
"remove-engine", "settings-get", "settings-set", "toggle-tor",
@ -883,7 +890,12 @@ function isSettingsPage(sender) {
{
const handle = ipcMain.handle.bind(ipcMain);
ipcMain.handle = (channel, fn) => handle(channel,
SETTINGS_ONLY.has(channel) || SETTINGS_SHARED.has(channel)
HERMES_ONLY.has(channel)
? (e, ...args) => {
if (!hermesWin || hermesWin.isDestroyed() || e.sender !== hermesWin.webContents) throw new Error(`${channel}: messages window only`);
return fn(e, ...args);
}
: SETTINGS_ONLY.has(channel) || SETTINGS_SHARED.has(channel)
? (e, ...args) => {
const ok = isSettingsPage(e.sender) || (SETTINGS_SHARED.has(channel) && chrome && e.sender === chrome.webContents);
if (!ok) throw new Error(`${channel}: settings only`);