From 18790a7e4e33511c569fa61a937019033ee27962 Mon Sep 17 00:00:00 2001 From: type-two Date: Wed, 8 Jul 2026 20:29:53 +1000 Subject: [PATCH] fix(flowext): loopback-only queue server, real self-heal, per-machine browser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three bugs, all found standing up a second rig on m3ultra: 1. SECURITY: HTTPServer(("", 8017)) bound 0.0.0.0 with no auth, and POST /save base64-writes bytes to an absolute `dest` taken straight from the request body. Anyone on the same wifi could write arbitrary files as this user — drop a ~/Library/LaunchAgents plist and you have code execution. It was live on ultra (verified: `TCP *:8017 (LISTEN)`, 204 from 192.168.1.249). Now binds 127.0.0.1; FLOW_BIND overrides for a tailnet IP (utun-routed, LAN still can't reach it). 2. The launchd "self-heal" never healed anything. launch.sh backgrounds the queue server and exits; without AbandonProcessGroup launchd SIGKILLs the process group on exit, so every 10-min tick started a server that died a second later. The server that was actually up had been started by a manual ./launch.sh. Verified after the fix: kill -> 000 -> kickstart -> 204 on a fresh pid. 3. launch.sh hard-coded "Brave Browser" in the osascript. The extension is loaded into Chrome on m3ultra. FLOW_BROWSER now names it (default Brave, unchanged for ultra); m3ultra's plist sets "Google Chrome". Also chmod +x install.sh launch.sh (both had lost the bit). Co-Authored-By: Claude Opus 4.8 --- games.monsterrobot.flowrinse.plist | 7 +++++++ install.sh | 0 launch.sh | 9 ++++++--- local_server_example.py | 11 +++++++++-- 4 files changed, 22 insertions(+), 5 deletions(-) mode change 100644 => 100755 install.sh diff --git a/games.monsterrobot.flowrinse.plist b/games.monsterrobot.flowrinse.plist index f212596..58945eb 100644 --- a/games.monsterrobot.flowrinse.plist +++ b/games.monsterrobot.flowrinse.plist @@ -21,6 +21,13 @@ /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + + AbandonProcessGroup + + RunAtLoad diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 diff --git a/launch.sh b/launch.sh index 330df26..24c24c2 100755 --- a/launch.sh +++ b/launch.sh @@ -32,10 +32,13 @@ fi # 2. open or focus ONE Flow tab (reuses an existing one so it can't double-run). # Only `activate` (steal system focus) when opening fresh — on the 10-min launchd -# tick an existing tab is re-selected inside Brave without yanking you out of +# tick an existing tab is re-selected inside the browser without yanking you out of # whatever you're doing. Selecting the tab also keeps Memory Saver from discarding it. +# +# Must name the browser the EXTENSION is loaded into. ultra = Brave, m3ultra = Chrome. +BROWSER="${FLOW_BROWSER:-Brave Browser}" osascript < if a remote box + # must enqueue — a tailnet IP is routed over utun, so the LAN still can't reach it. + # Never set it back to "" / 0.0.0.0. + host = os.environ.get("FLOW_BIND", "127.0.0.1") + print(f"--- Flow queue on http://{host}:{port} ---") print(f"queue: {QUEUE_FILE if os.path.exists(QUEUE_FILE) else '(demo — no queue.jsonl)'}") print(f"pending: {sum(1 for t in load_queue() if t['id'] not in done_ids())}") - HTTPServer(("", port), Handler).serve_forever() + HTTPServer((host, port), Handler).serve_forever() if __name__ == "__main__": import sys