super-productivity/electron
johannesjo c12982f1f9 feat(electron): add sync-path-resolver for renderer-supplied paths
Phase 1 of the fix for #8228, simplified after KISS review.

The earlier draft (commit 5cb83b41a, since reverted) introduced a
multi-grant capability store with opaque grantIds and a feature
discriminator. Review showed the abstraction was overhead: this app
has exactly one user-pickable filesystem location (the sync folder).
Backgrounds will go through copy-to-cache, not folder grants;
plugins do not get folder grants; backups use a main-derived path.
And the opaque grantId added zero marginal security over a featureless
{relativePath} API since an XSS in the renderer would just replay the
id from memory. The security boundary is "main owns the canonical root
and the resolver logic", not the id.

So: drop the store, keep the resolver. resolveSyncPath takes
(syncFolderPath, relativePath, userDataDir) and returns the vetted
absolute path. Layered defenses:

  - syncFolderPath canonicalized every call (folder may have moved
    since startup); missing/inaccessible root denies
  - canonical root must not be userData or live inside it (a user who
    picks userData as their sync folder would otherwise hand the
    renderer authority over settings/grants/db)
  - relativePath may be '' or '.' for LIST/CHECK ops on the root;
    anything else must not be absolute and must not escape
  - leaf symlinks refused (v1 policy; O_NOFOLLOW alternative is a
    follow-up that needs cross-platform care)
  - canonical resolved path (or deepest existing ancestor when the
    leaf doesn't exist yet) must still live inside the canonical
    root — catches symlinks/junctions in intermediate directories
    and case-fold / 8.3-shortname aliases
  - ancestor walk fails CLOSED on EACCES; only ENOENT lets us walk
    up. A permission-restricted ancestor must not silently allow.

Errors are opaque (PathNotAllowedError, no path in message) and the
stack is stripped — IPC handlers further sanitize before returning to
the renderer.

Phase 2 will wire this into FILE_SYNC_SAVE/LOAD/REMOVE/LIST_FILES and
CHECK_DIR_EXISTS, move syncFolderPath ownership from the renderer's
privateCfg to a main-side simple-store key, and add a re-confirm
migration on first launch.

16 unit tests cover the rejection cases from #8228's test plan plus
the EACCES-fail-closed branches that came out of the KISS review.
2026-06-09 22:23:47 +02:00
..
assets/icons fix: wrong icon for kde title bar 2025-07-22 20:42:28 +02:00
ipc-handlers fix(electron): validate URL scheme before shell.openExternal/openPath (GHSA-hr87-735w-hfq3) (#8210) 2026-06-09 17:29:18 +02:00
scripts refactor(electron): bundle preload script with esbuild to support sandbox mode 2026-03-22 19:38:21 +01:00
shared-with-frontend fix: harden local file URL guard 2026-06-09 19:32:09 +02:00
task-widget Feat/task widget global shortcut (#7099) 2026-06-09 16:11:16 +02:00
wayland-idle-helper Add ext-idle-notify backend for Wayland idle detection (#7337) 2026-04-24 16:50:24 +02:00
app-control.test.cjs fix(electron): respect tray title settings #7823 (#8097) 2026-06-08 12:07:09 +02:00
backup.ts fix(electron): restrict loadBackupData IPC to the backup directory (#8206) 2026-06-09 15:29:06 +02:00
clear-stale-idb-locks.ts Feat/to me it looks like there are lots of 60dd04 (#7280) 2026-04-20 12:04:38 +02:00
clipboard-image-handler.test.cjs fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
clipboard-image-handler.ts fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
common.const.ts chore: update electron to v41.x (#7097) 2026-04-17 18:12:43 +02:00
CONFIG.ts Increase ping interval and idle time in order to not waste CPU cycles. (#6227) 2026-01-28 15:37:50 +01:00
debug.ts refactor: rename overlay-indicator to task-widget 2026-03-30 22:00:47 +02:00
electronAPI.d.ts fix(plugins): harden nodeExecution grants (#8205) 2026-06-09 18:16:41 +02:00
error-handler-with-frontend-inform.ts fix(error-handling): prevent [object Object] from appearing in error messages 2026-01-02 15:40:14 +01:00
file-path-guard.test.cjs fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
file-path-guard.ts fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
full-screen-blocker.ts fix(security): harden XSS sinks and add Origin check (#7413) 2026-05-06 21:37:06 +02:00
gpu-startup-guard.ts fix(electron): add GPU startup guard for confined Linux packages 2026-04-20 18:35:31 +02:00
idle-time-handler.ts fix(electron): retry Wayland idle helper startup (#7527) 2026-05-10 22:35:33 +02:00
indicator.test.cjs fix(electron): respect tray title settings #7823 (#8097) 2026-06-08 12:07:09 +02:00
indicator.ts fix(electron): respect tray title settings #7823 (#8097) 2026-06-08 12:07:09 +02:00
ipc-handler-wrapper.test.cjs fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
ipc-handler-wrapper.ts fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
ipc-handler.ts feat(electron): add Local REST API for desktop automation (#6981) 2026-03-28 13:35:04 +01:00
jira.ts fix(jira): honor no_proxy for electron requests #6324 (#8177) 2026-06-09 15:00:43 +02:00
local-file-sync.test.cjs fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
local-file-sync.ts fix(security): restrict renderer-supplied filesystem IPC paths (#8223) 2026-06-09 18:16:22 +02:00
local-rest-api.ts fix(security): harden XSS sinks and add Origin check (#7413) 2026-05-06 21:37:06 +02:00
lockscreen.ts fix(electron): restore macOS lock screen by correcting osascript quoting 2026-04-16 19:47:52 +02:00
main-window.ts fix(electron): compare host exactly before in-window navigation 2026-06-09 19:32:09 +02:00
main.ts fix(electron): improve protocol URL handling and register URL scheme on Linux 2026-03-05 16:45:05 +01:00
plugin-node-executor.test.cjs fix(plugins): harden nodeExecution grants (#8205) 2026-06-09 18:16:41 +02:00
plugin-node-executor.ts fix(plugins): harden nodeExecution grants (#8205) 2026-06-09 18:16:41 +02:00
plugin-oauth.ts Improve OAuth error handling and reporting (#7445) 2026-05-01 18:45:11 +02:00
preload.ts fix(plugins): harden nodeExecution grants (#8205) 2026-06-09 18:16:41 +02:00
protocol-handler.ts feat(sync): add OneDrive sync provider with PKCE auth (#7523) 2026-05-26 15:31:06 +02:00
proxy-agent.test.cjs fix(jira): honor no_proxy for electron requests #6324 (#8177) 2026-06-09 15:00:43 +02:00
proxy-agent.ts fix(jira): honor no_proxy for electron requests #6324 (#8177) 2026-06-09 15:00:43 +02:00
shared-state.ts fix: refactor tray handling to use shared state for task and countdown visibility 2025-11-28 18:53:00 +01:00
simple-store.test.cjs fix(electron): harden simple store writes (#7297) 2026-04-21 15:03:30 +02:00
simple-store.ts fix(electron): harden simple store writes (#7297) 2026-04-21 15:03:30 +02:00
start-app.ts fix(macOS): gracefully quit app (#7733) 2026-05-27 17:13:43 +02:00
sync-path-resolver.test.cjs feat(electron): add sync-path-resolver for renderer-supplied paths 2026-06-09 22:23:47 +02:00
sync-path-resolver.ts feat(electron): add sync-path-resolver for renderer-supplied paths 2026-06-09 22:23:47 +02:00
task-widget.test.cjs Feat/task widget global shortcut (#7099) 2026-06-09 16:11:16 +02:00
tsconfig.electron.json feat(sync): add OneDrive sync provider with PKCE auth (#7523) 2026-05-26 15:31:06 +02:00
various-shared.ts Feat/task widget global shortcut (#7099) 2026-06-09 16:11:16 +02:00