Verify the security posture¶
Security pages are easy to write and hard to check. This one is built the other way around: it takes CodeNavi's central access-control claim and turns it into commands you can run against your own install, in about ten seconds, with nothing but curl.
The occasion for it was real. In 2026 a critical unauthenticated remote-code-execution flaw was disclosed in a widely-used CI vendor's MCP server (GHSA-xv5j-cwgj-22r4, found and written up by Omri Dar at Remedio): a request carrying Host: localhost and no Origin header passed for authentication, and the tool behind it ran pipelines with the organization's stored token. Two spoofed headers, no credentials. Customers asked us the obvious question; this page is the answer, and the proof.
The claim, and the command¶
CodeNavi never reads Host or Origin to decide access. The same request gets a 401.
curl -s -o /dev/null -w "%{http_code}\n" \
-H "Host: localhost" \
http://127.0.0.1:8765/ui/api/index/overview
| Request | Result | Why |
|---|---|---|
Host: localhost, no Origin |
401 |
The exact bypass from the advisory |
Host: evil.example |
401 |
The Host header changes nothing |
Authorization: Bearer wrong |
401 |
Compared in constant time |
POST /mcp, no credentials |
401 |
Tools sit behind the same gate |
Authorization: Bearer <your token> |
200 |
The only thing that opens the door |
Run all five against your own instance. If any line returns something other than what you see here, that is a vulnerability report we want — see Vulnerability disclosure.
The three root causes, held against CodeNavi¶
The advisory is precise about what went wrong, which makes it a fair checklist to hold any MCP server against — including this one.
1. Headers used as authentication¶
What failed there: an allowlist check accepted any request whose Host appeared in it, and a second check treated a missing Origin as permission granted. Both values are chosen by the caller.
What CodeNavi does: access is decided by one thing — a bearer token, compared in constant time. No header influences that decision, and there is no code path where an absent header means yes. The routes that don't require the token are the static web-UI and setup-wizard assets plus a handful of metadata endpoints that return identical product information to everyone; deployment details go only to a caller who authenticates, and /health discloses in tiers.
2. Listening on every interface by default¶
What failed there: the server bound 0.0.0.0 out of the box, so the header checks meant to stop a browser attack were instead the only thing standing between the open internet and the tool surface.
What CodeNavi does: the installer publishes to 127.0.0.1 and always generates a token. The startup auth-exposure guard evaluates the interface the server actually binds — not a config value that merely claims one — and a network-reachable bind without a token is refused or loudly flagged, never silent. Turning that off takes a deliberate, documented environment variable. Exposing the server on purpose is covered in Remote access.
3. A tool that ran caller-supplied code¶
What failed there: past the header check, anyone could invoke a tool that executed an arbitrary pipeline definition using the organization's stored credentials — shell access, secrets, cloud identity.
What CodeNavi does: no CodeNavi tool executes code a caller supplies. The server searches, reads, and summarizes an index you built. File reads are confined to the codebases you configured and pass through the same secret redaction the indexer uses, so a token holder cannot read their way to an API key. The opt-in crawler is the only component that reaches the network, and it refuses private, loopback, and cloud-metadata targets.
What auditing against it changed anyway¶
Answering the three root causes is not the same as having nothing to tighten. Reviewing our own code against the advisory produced two changes, both shipped:
- The script-hook directory is pinned. CodeNavi can run a shell script of yours when an index or crawl finishes. The setting naming that directory is no longer writable to arbitrary paths over the API — it accepts only the documented hooks mount. The machine's owner is unaffected: setting it through the environment still works and still accepts any path. The boundary being enforced is "arrived over the network," not "has a shell on the box."
- DNS-rebinding protection in the tokenless posture. CodeNavi supports one posture without a token: bound to localhost only, on a single-user machine. There, the MCP endpoint now validates
HostandOriginso a malicious web page cannot reach it by pointing a domain it controls at your loopback address. Where a token is set, this check stays off by design — it would reject legitimate LAN or mesh-network clients while adding nothing the token doesn't already provide. It is a second lock, never the lock: a check that a missing header satisfies can harden an endpoint, but it can never authenticate one — which is precisely how the original bypass got in.
What this page does not claim¶
Not "CodeNavi has no vulnerabilities." It claims that this specific failure class is answered, that the defaults fail closed, and that you can check the central claim yourself from your own terminal.
- The token is all-or-nothing. One bearer token grants every tool — search, indexing, settings. There is no read-only credential today; if your deployment needs one, that is a conversation we want to have. The same limit is stated in the NSA guidance mapping.
- Self-hosted means your configuration is yours. Every protection here is a default we picked, and every one can be overridden. Override them knowingly.
- Credit where due: the flaw that prompted this page was found and responsibly disclosed by outside researchers, and fixed promptly by the vendor. We read the write-up and audited against it; the two changes above are the result. Found something we missed? We would rather hear it from you than read it in someone's advisory — Vulnerability disclosure is the door.