The short version
- A server bound to 127.0.0.1 cannot be reached from other machines. It can be reached by any web page open on the same machine, which is how several AI developer tools were attacked.
- Luminair's Router shares local models between Macs through a loopback proxy. An audit in September 2026 found that its command endpoint trusted anything from 127.0.0.1.
- Now every control call needs a per-install token, and any request with a non-localhost Origin is refused on every path.
- Pairing moved to SPAKE2, so the 6-digit code cannot be tested offline, and sharing is off in both directions until you turn it on.
The browser is a program on your Mac.
Local AI tooling runs on ports. A model server, an MCP server, a debugging proxy: each opens a port on your machine so other programs can talk to it. Binding that port to 127.0.0.1, the loopback address, keeps other computers out. It is tempting to stop there.
The problem is who else is on your machine. Your browser is, and it runs code from every site you visit. A page can ask the browser to send a request to http://127.0.0.1 on any port. It may not be able to read the answer, but for a port that does something, such as starting a process, sending is enough.
That is exactly what happened to the MCP Inspector, the official tool for testing MCP servers. The GitHub advisory for CVE-2025-49596 says versions below 0.14.1 were “vulnerable to remote code execution due to lack of authentication between the Inspector client and proxy, allowing unauthenticated requests to launch MCP commands over stdio.” Oligo Security, who reported it, described the attack plainly: “When a victim visits a malicious website, the vulnerability allows attackers to run arbitrary code on the visiting host”.
The MCP specification's own transport rules now carry a security warning for HTTP servers: they “MUST validate the Origin header on all incoming connections to prevent DNS rebinding attacks”, “SHOULD bind only to localhost”, and “SHOULD implement proper authentication for all connections”.
The wider picture has not been kind either. In December 2025 Bitsight scanned the internet and found “Roughly 1,000 exposed MCP servers with no authorization in place”, pointing out that the spec says “Authorization is OPTIONAL for MCP implementations.” In April 2026, The Register and The Hacker News covered OX Security's report on MCP's STDIO transport, where a configuration becomes a command. The Hacker News reports ten vulnerabilities across popular projects and reports that Anthropic “declined to modify the protocol's architecture, citing the behavior as ‘expected.’”
Two Macs, one pool of local models.
Router is a Team+ feature that landed on 6 September 2026. It pairs Luminair Macs on the same network so one can borrow the other's power. Point any Ollama or OpenAI-compatible client at a local endpoint, and each request goes to whichever paired Mac already holds the model and is least busy. A session can also push a build or test run to a peer.
It does not merge memory or GPUs. The settings page says so: “two Macs run two things at once, not one thing twice as fast.”
Under the hood there are two servers. A peer server faces the network and speaks HTTPS, with each Mac's certificate pinned at pairing. A proxy listens only on 127.0.0.1, port 47413 by default, for your own tools. That proxy is the loopback port this post is about. It is an attack surface in exactly the way a local MCP server is.
“Any request from 127.0.0.1.”
Within a day of Router's first commit, an audit went through it. The finding that matters most here is recorded in the source, in the audit's own words: /router/run “used to accept any request from 127.0.0.1, which is exactly what a web page open in a browser on this Mac can send.” That endpoint runs shell commands. The same surface could also show the pairing code.
The fix has two parts that work together. First, a token. On first start, Router writes a random 48-character secret to router-proxy.token in Luminair's user data folder, readable only by your user account. Every /router/* call must present it in a header. The router command sessions use reads the file, and the path is handed to sessions in an environment variable. A web page cannot read your files, so it cannot present the token.
Second, no web pages at all. Browsers stamp cross-site requests with an Origin header naming the site that sent them. Router refuses any request whose Origin is not localhost, on every path, with a plain answer:
if (browserOrigin(req)) return sendJson(res, 403, { error: 'Router does not answer requests from web pages.' }); // --- local control surface: token required --- if (p.startsWith('/router/') && (req.headers.origin || !localAuthorized(req))) { // 401: needs the local proxy token }
Note the second line: a /router/* control call is refused if it carries any Origin, even a localhost one. Real control callers are command-line tools, and they never send one.
/router/*)? Then: no Origin at all, and the token matches?401Router control needs the local proxy tokenStatus, nodes, models list, run a command.proxyHandler. Inference stays open to local programs without a token, as an Ollama port is, so existing clients keep working. Engine administration and every Router control call do not.A later fix, on 7 September, closed the same gap from the other side. A paired Mac that sends model requests to yours may use models but not administer the engine, and only transport headers are forwarded to Ollama or LM Studio. The caller's tokens, cookies and credentials stay on the Mac they came from.
Six digits are fine. Once.
To pair two Macs, one shows a 6-digit code and you type it into the other. Six digits is a million possibilities. That is plenty if an attacker gets three guesses. It is nothing if they can guess at leisure.
The first version proved knowledge of the code with a keyed hash over the pairing messages. The audit spelled out the problem in the source: “a spoofed LAN endpoint could capture one attempt and test all 1,000,000 codes at leisure.” Anyone on the same Wi-Fi could pose as the Mac you meant to pair with, record your one attempt, and crack the code on their own machine.
Router now uses SPAKE2, a password-authenticated key exchange. The idea, without the maths: each side mixes the code into a random value it sends. Only someone who knows the code can unmix the other side's value and arrive at the same shared secret. An impostor who does not know the code learns nothing it can test later. Each attempt is one live guess, and then it is spent.
A few details make it hold up. The group is the 2048-bit one from RFC 3526, and the prime is read from OpenSSL's built-in table rather than typed in by hand. Incoming values outside the right subgroup are rejected. Both Macs' certificate fingerprints are part of the exchange, so a relay in the middle that swaps certificates fails the final check. A peer is stored only after both sides have proved they know the code, and the resulting token is stored encrypted through the operating system's credential store, never in plain text in a config file.
There is a test for the maths too. It checks that the prime is a safe prime and that the fixed values sit in the right subgroup, because a hand-rolled key exchange with a wrong constant fails silently.
Pairing is not permission.
The last change is about defaults. Router has two independent switches: Use other Macs sends your work out, and Let other Macs use this computer lets paired Macs send work in. After the audit, both start off on a fresh install. Pairing alone opens nothing; the source comment says the user turns each direction on deliberately.
Direction
Sessions on this computer may push builds, tests and local-model requests to the paired Macs. Off keeps every job here; pairing is kept.
Paired Macs may send local-model requests here. Off stops incoming jobs and hides this computer from nearby discovery.
“Off” is meant literally. With inbound off, your Mac stops sending its discovery beacon, so nothing on the network learns it exists. A paired Mac that asks for its status gets one answer, that it is closed, with no load figures and no model list, and every work request is refused. With outbound off, the local model lists show only this Mac's models, so nothing is routed away by surprise.
One exception is deliberate. Showing a pairing code counts as consent: while the code is valid, your Mac advertises itself and accepts pairing, even with inbound off. When the code expires or is used, it closes again.
Two Macs, five minutes.
- 1On both Macs, open your avatar at the bottom left, then Settings › Router, and turn Router on. Router needs a Team+ plan.
- 2On the Mac you want to share, click Show code. On the other, pick that Mac from the list and type the 6 digits within five minutes.
- 3Under Direction, turn on only what you need. Leave shell commands off unless you trust every paired Mac with a terminal.
Checked, and not claimed.
What this post does not claim
- That Router has had an outside audit. The audit here was our own, recorded in the commit history.
- That the token protects you from malware already running as your user. A program with your file access can read it.
- That the model endpoints need a token. Plain inference stays open to local programs, like an Ollama port, and closed to web pages.
- That Router is related to the MCP STDIO report. It is not an MCP server; the lesson about local ports is the same.
Sources
- GitHub Advisory Database · 13 June 2025MCP Inspector proxy server lacks authentication between the Inspector client and proxy (CVE-2025-49596)
- Oligo Security · 2025Critical RCE vulnerability in Anthropic MCP Inspector (CVE-2025-49596)
- Model Context Protocol · Specification 2025-06-18Transports
- Bitsight · 11 December 2025It's 2 AM. Do You Know Which AIs Your MCP Server Is Talking To?
- The Register · 16 April 2026Anthropic won't own MCP 'design flaw' putting 200K servers at risk, researchers say
- The Hacker News · 20 April 2026Anthropic MCP Design Vulnerability Enables RCE, Threatening AI Supply Chain
Share models, not your Mac
Pair two Macs, turn on only the direction you need, and keep shell commands off.