[P0][SECURITY] BUG-41: shipped brain binds ALL interfaces with no auth — the launcher's loopback-lock and auth key are inert (EL_HTTP_BIND_HOST / EL_HTTP_AUTH_KEY exist nowhere in the engine) #110
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
BUG-41. Filed by Neuron (Tim's instance) 2026-08-05. Every fact below was measured first-hand for this filing unless explicitly marked otherwise.
What is wrong
The macOS launcher believes it starts the brain loopback-locked and authenticated. It does not. The two environment variables it sets to achieve that —
EL_HTTP_BIND_HOSTandEL_HTTP_AUTH_KEY— do not exist anywhere in the engine. Nothing reads them. The brain binds all interfaces and serves every request unauthenticated, while the launcher logsloopback-locked.In plain terms: on shared wifi — a coffee shop, an office, a hotel, a conference — anything else on that network can read and write the user's memory. No password, no token, no prompt.
Evidence
1. The launcher's intent (and its false log line)
installer/macos/neuron-daemons.sh— round-7 copy at_wt-beta-round7/resources/macos-arm64/neuron-daemons.sh. It mints a per-install secret and passes both knobs:2. Raw byte search of the shipped brain
Binary:
_wt-beta-round7/resources/macos-arm64/neuron— this isSOUL_BINperneuron-daemons.sh:31. Mach-O 64-bit arm64, 899,424 bytes, md585a19bd6e83a9f96f60a7b7a17e5745d, mtime 2026-08-05 20:45.strings -a <bin> | grep -cx <name>:EL_HTTP_TIMEOUT_MSNEURON_PORTNEURON_LLM_0_URLEL_HTTP_AUTH_KEYEL_HTTP_BIND_HOSTAUTH_KEYBIND_HOSTEL_HTTP_TIMEOUT_MSandNEURON_PORTare present, which proves the technique finds env-var names the binary genuinely reads. The auth and bind knobs are simply not in there.3. Source confirms this is not a packaging accident
A tree-wide search of every
*.el,*.elh,*.cand*.h— including the vendored runtimevendor/el-runtime/v1.0.0-20260501/el_runtime.c— returns zero hits forEL_HTTP_BIND_HOSTandEL_HTTP_AUTH_KEY. The only knob of that family that exists isEL_HTTP_TIMEOUT_MS(el_runtime.c:780, default 60000). These two were never implemented.4. Live on this machine, 2026-08-05 22:23:42 CDT
*:7770, not127.0.0.1:7770. The MCP wrapper and proxy are wide open too.5. Exploited — measured earlier today, NOT re-run for this filing
Marked separately because it is the one item here I did not personally re-execute (the filing pass was read-only on the live daemons): a plain HTTP GET issued from the machine's own LAN address returned 200, and an unauthenticated POST from the LAN wrote a memory and came back
{"ok":true}. Read and write, from off-box, with no credential.This is pre-existing, not a round-7 regression
The round-6 and round-7 brains are byte-identical — both md5
85a19bd6e83a9f96f60a7b7a17e5745d, both 899,424 bytes. Every DMG built so far ships this.What the fix needs (engine-side, yours)
EL_HTTP_BIND_HOSTin the runtime listener, and make the default127.0.0.1— safe when unset, not merely safe when the launcher remembers to set it.EL_HTTP_AUTH_KEYas a required shared-secret check on every route whenever it is set. The launcher already generates and stores the secret in the Keychain, so the app side is done the moment the engine honors it.loopback-lockedlog line conditional on the bind actually having succeeded. A log line that asserts a security property it never verified is how this stayed invisible.Until (1) and (2) exist in the binary, no launcher-side change can fix this — the app cannot lock a door the engine does not have. That is why this is filed engine-side rather than as an app bug.
Suggested gate
Worth a CI assertion once implemented: boot the built brain and fail the build if
lsofshows anything other than a loopback bind, and if an unauthenticated request succeeds. This class of defect is invisible to every test that runs on localhost.Cross-refs: neuron#62 (make inference endpoint + auth token configurable) touches the same auth surface. neuron-ui#213 is the 2026-08-03 bug harvest this continues.
Independent corroboration from the soul's own log
2026-08-05. The brain announces the wide bind itself. From
~/neuron-dev-stack/logs/dev-soul.err.logon the live instance:[::]is the IPv6 any-address, dual-stack — every interface, which is what thelsofline in the report shows asTCP *:7770 (LISTEN). So this is not an artifact of howlsofrenders a socket: the HTTP layer is being told to listen on the any-address and says so.This also confirms there is no code path consulting a bind-host preference at listener setup — consistent with the byte search finding zero occurrences of
EL_HTTP_BIND_HOSTin both the shipped brain and the entire source tree.