Skip to content

Security: Capernaum-user/peek-bridge

Security

SECURITY.md

Security

Why this document exists

In April 2026 (tracked publicly as REF6598), an Obsidian plugin was abused to drop and launch a local Windows executable, ending in a RAT (PHANTOMPULSE). The attack shape was "plugin talks to a local .exe" — the same silhouette as peek-bridge (this plugin) talking to the Peek desktop app. Because the silhouette matches, this document states precisely what peek-bridge does and does not do, verified against the actual source in this repository rather than asserted from memory.

What peek-bridge does not do

  • No remote network communication. peek-bridge makes no HTTP(S) requests, no WebSocket connections, and calls no remote API. It never contacts any server, including Peek's own vendor. There is nothing in main.js that opens a network socket.
  • No dynamic code execution. peek-bridge never evaluates strings as code (no eval, no new Function, no remotely-fetched script).
  • No access outside the vault other than launching the local Peek app. peek-bridge does not read or write arbitrary files on disk. The only filesystem/process touches outside the Obsidian vault are the ones listed below, and they are all local, all fixed-path, and none of them are driven by remote or vault-content input.

What peek-bridge does — the full IPC/process surface

  1. Launches the local Peek desktop app, if present and not already running. child_process.spawn(exePath, [], { detached: true, stdio: 'ignore' }). No arguments are passed and no shell is invoked (spawn without shell: true runs the executable directly). exePath is resolved from exactly two sources, both local and both under the user's control, never from the network or from vault content:
    • the path the user typed into this plugin's own settings field ("Peek executable path"), if it points to a file that exists, or
    • one of four fixed candidate paths under %LOCALAPPDATA%\Peek, %LOCALAPPDATA%\Programs\Peek, %ProgramFiles%\Peek, or %ProgramFiles(x86)%\Peek, checked with fs.existsSync — nothing else on disk is probed.
  2. Checks whether Peek is already running, to avoid spawning a second copy, via child_process.exec('tasklist /FI "IMAGENAME eq peek.exe" /NH', ...). This is a single hardcoded literal command string — no user input, vault content, or remote data is ever interpolated into it, so there is no injection surface here even though exec itself goes through a shell. This check only runs on win32; it is a no-op everywhere else.
  3. Writes one marker file inside the vault's sticker folder (.peek-workspace.request, a dotfile so it never shows up as a note), containing only the current ISO timestamp, so the Peek desktop app knows to show its sticky windows. This goes through Obsidian's own app.vault.adapter.write API, scoped to the vault.
  4. Reads one presence file inside the vault (.peek-desktop-state.json), written only by the Peek desktop app, to show an "on desktop" badge and detect stickies that drifted out of sync. This is read-only: peek-bridge never writes to this file, and a missing/corrupt file is treated as "no presence" rather than an error.

Everything else peek-bridge does — listing, creating, and opening sticky notes — goes through the standard Obsidian vault API and stays inside the configured sticker folder.

Reporting a vulnerability

Please open a GitHub issue on this repository. There is no bug bounty; this is a hobby-scale free plugin maintained by one person.

There aren't any published security advisories