mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
* fix(electron): block executable launch via shell.openPath window.ea.openPath is reachable by any plugin, same-origin iframe plugin, or renderer XSS, and its guard only blocked UNC/remote paths (NTLM leak, GHSA-hr87). shell.openPath hands a local file to the OS handler, and on Windows ShellExecute runs .bat/.cmd/.vbs/.hta/... from a plain file with no exec bit. Chained with a writable-dir drop (e.g. FILE_SYNC_SAVE into the local-file sync folder) or a malicious synced FILE attachment clicked by the user, that is renderer -> native code execution bypassing the nodeExecution consent gate. Add hasExecutableFileExtension() (normalizes Windows trailing dots/spaces and NTFS alternate data streams) and refuse those paths at the openPath sink. Applied at the sink, not in the shared isPathSafeToOpen, so link/image rendering (where a remote https://.../x.exe is legitimate) is unaffected. * fix(electron): close # filename bypass in openPath executable gate The executable-extension check split every path on `?`/`#` to drop a URL query/fragment, but `#` is a legal Windows/NTFS filename char (and both `#` and `?` are legal on POSIX). For a bare filesystem path that split truncated the real filename: `C:\sync\evil.txt#.bat` was read as `.txt` and allowed, yet ShellExecute runs it as `.bat` — defeating the gate via the same drop-a-file-then-openPath vector the fix targets. Gate the query/fragment split behind an actual `file:` scheme so real filenames keep their extension. Also add well-known ShellExecute/launcher vectors the curated denylist missed: settingcontent-ms, appref-ms, library-ms, wsc, chm, hlp, diagcab, msix/appx family (Windows) and pkg, terminal, fileloc, inetloc (macOS). Adds regression tests for both. * fix(electron): require file:// (not bare file:) before query/fragment split The executable-extension gate stripped a URL query/fragment for any string starting with `file:`. On POSIX `#`, `?` and `:` are all legal filename chars, so a file whose name merely starts with the literal `file:` (e.g. `file:notes.txt#.sh`) was mis-parsed as a URL and its real `.sh`/`.desktop` extension hidden. Require the `//` of an actual `file://` URL so only genuine URLs get the query/fragment split; bare paths keep their real extension. |
||
|---|---|---|
| .. | ||
| assets/icons | ||
| ipc-handlers | ||
| scripts | ||
| shared-with-frontend | ||
| task-widget | ||
| wayland-idle-helper | ||
| app-control.test.cjs | ||
| backup.ts | ||
| bundled-plugin-ids.test.cjs | ||
| clear-stale-idb-locks.ts | ||
| clipboard-image-handler.test.cjs | ||
| clipboard-image-handler.ts | ||
| common-const.test.cjs | ||
| common.const.ts | ||
| CONFIG.ts | ||
| debug.ts | ||
| electronAPI.d.ts | ||
| error-handler-with-frontend-inform.ts | ||
| exec.test.cjs | ||
| file-path-guard.test.cjs | ||
| file-path-guard.ts | ||
| full-screen-blocker.ts | ||
| gpu-startup-guard.ts | ||
| idle-time-handler.ts | ||
| image-cache.test.cjs | ||
| image-cache.ts | ||
| indicator.test.cjs | ||
| indicator.ts | ||
| ipc-handler-wrapper.test.cjs | ||
| ipc-handler-wrapper.ts | ||
| ipc-handler.ts | ||
| jira.ts | ||
| local-file-sync.test.cjs | ||
| local-file-sync.ts | ||
| local-rest-api.ts | ||
| lockscreen.ts | ||
| main-window.ts | ||
| main.ts | ||
| navigation-guard.test.cjs | ||
| navigation-guard.ts | ||
| plugin-node-consent-store.test.cjs | ||
| plugin-node-consent-store.ts | ||
| plugin-node-executor.test.cjs | ||
| plugin-node-executor.ts | ||
| plugin-oauth.ts | ||
| preload.ts | ||
| protocol-handler.test.cjs | ||
| protocol-handler.ts | ||
| proxy-agent.test.cjs | ||
| proxy-agent.ts | ||
| shared-state.ts | ||
| simple-store.test.cjs | ||
| simple-store.ts | ||
| start-app.ts | ||
| sync-path-resolver.test.cjs | ||
| sync-path-resolver.ts | ||
| task-widget.test.cjs | ||
| tsconfig.electron.json | ||
| various-shared.test.cjs | ||
| various-shared.ts | ||