Skip to content

Scope the URL ACLs to one account and stop widening system firewall rules - #7

Open
neoliminal wants to merge 1 commit into
ElodineOfficial:mainfrom
neoliminal:security/urlacl-and-firewall-scope
Open

Scope the URL ACLs to one account and stop widening system firewall rules#7
neoliminal wants to merge 1 commit into
ElodineOfficial:mainfrom
neoliminal:security/urlacl-and-firewall-scope

Conversation

@neoliminal

Copy link
Copy Markdown
Contributor

Three separate over-reaches in setup-lan.bat. Grouped because they're all one file and one theme, but happy to split if you'd rather review them apart.

1. user=Everyone on the URL reservations

setup-lan.bat:142,150 ran netsh http add urlacl url=http://+:PORT/ user=Everyone for 8080 and 11435. That's a permanent, machine-wide grant letting any local account — including a low-privilege or service account — bind those ports on every interface. An account that starts before the real server could squat 8080 and serve a look-alike login page to phones on the LAN, harvesting the chat password.

Now granted to the account running the setup. An existing Everyone grant is detected and replaced rather than reported as "already exists", so re-running fixes an affected install. The account is printed, since elevating with a different admin account would grant it to the wrong one — worth seeing before it happens.

The reservation URL itself is unchanged (http://+:PORT/), only the grantee.

2. The built-in mDNS rule was widened to the Public profile

setup-lan.bat:101 ran set rule name="mDNS (UDP-In)" new enable=yes profile=private,public. That rule isn't ours — changing it affects every application using mDNS, applies on untrusted networks, and wasn't in the undo instructions.

Both the comment above it and the message it prints already said Private only; the command was the odd one out. It now enables the rule without touching its profile scope, and the fallback Gemma4-mDNS rule is Private-only.

3. LAN rules for two loopback-only services

Ports 11434 and 11435 were opened to the local subnet, but both services bind 127.0.0.1launch.bat:1389 passes --host 127.0.0.1, and the search proxy listens on http://127.0.0.1:11435/. Nothing on the LAN could reach them; the rules only stood to expose whatever else might bind those ports later.

Removed rather than left behind, so re-running cleans up an existing install. Only 8080, the port the phone actually talks to, keeps a rule. Undo instructions updated to match.

Testing

Dry-run with netsh stubbed out, confirming the new :ensure_urlacl subroutine dispatches correctly, %ACL_USER% resolves, and both the add and the re-scope branches behave. Note the existing rules were already correctly scoped to remoteip=LocalSubnet — that part was solid and is untouched.

Found during a security review.

…ules

Three separate over-reaches in the LAN setup:

The URL reservations for ports 8080 and 11435 were granted to
`Everyone`. That is a permanent, machine-wide grant letting any local
account -- including a low-privilege or service account -- bind those
ports on every interface. An account that starts before the real server
could squat 8080 and serve a look-alike login page to phones on the LAN,
harvesting the chat password. They are now granted to the account
running the setup, and an existing Everyone grant is detected and
replaced rather than reported as "already exists". The account is
printed, since elevating with a different admin account would grant it
to the wrong one.

The mDNS step widened the Windows built-in "mDNS (UDP-In)" rule to the
Public profile. That rule is not ours: changing it affects every
application using mDNS, applies on untrusted networks, and was not in
the undo instructions. Both the comment above it and the message it
prints already said Private only -- the command was the odd one out. It
now just enables the rule without touching its profile scope, and the
fallback Gemma4-mDNS rule is Private-only.

Ports 11434 and 11435 were opened to the local subnet but both services
bind 127.0.0.1 (launch.bat passes --host 127.0.0.1; the search proxy
listens on http://127.0.0.1:11435/). Nothing on the LAN could reach
them, and the rules only stood to expose whatever else might bind those
ports later. They are removed rather than left behind, and the undo
instructions are updated to match.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jmccardle

Copy link
Copy Markdown
Contributor

rebased onto 1.5.8, but Claude feels like arguing: jmccardle#11

ElodineOfficial added a commit that referenced this pull request Aug 21, 2026
@neoliminal - pin SHA-256 of engine + embed model (#8), strip run-flags from transferred state (#5), sanitize GGUF metadata reaching generated .cmd (#3), escapeHtml fallback (#4), firewall / URL ACL scoping (#7).
@wizzense - fall back to loopback when the LAN bind is denied (#10).
@jmccardle - Linux wine catch, roadmaps for Linux (#2).
@DawidKorach - stable port assignments, llama health registration in the CMD (#14, #15).

Co-authored-by: neoliminal <john.kipling.lewis@gmail.com>
Co-authored-by: wizzense <37890504+wizzense@users.noreply.github.com>
Co-authored-by: John McCardle <mccardle.john@gmail.com>
Co-authored-by: Dawid Korach <dawidk6@gmail.com>
@jmccardle

Copy link
Copy Markdown
Contributor

recommend closure - jmccardle#11 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants