Home/ Blog/ Security news/ Article
Blog · Security news

NASA AIT-GUI console has no login (CVSS 9.4), and the 2.5.2 patch still adds no authentication

AIT-GUI, NASA/JPL open-source operator console, binds to every interface with no login (CVSS 9.4). A browser can send commands, and the 2.5.2 fix adds no auth.

Open unlatched access panel on a spacecraft ground control operator console

An operator console is only as safe as the belief that nobody else can reach it, and that belief keeps failing. NASA and JPL's open-source AIT-GUI, the browser front end for their AMMOS Instrument Toolkit, reads its configured host address, ignores it, and binds to every network interface with no login, no CSRF token, and no cross-origin check. Researchers at Cycode showed that one unauthenticated request can relay a command straight to the instrument command bus. The affected code is the same shape we keep writing up in machine-learning dashboards. The subject changed to spacecraft. The mistake did not.

The advisory is GHSA-p9r8-2q67-fp86, rated CVSS 9.4 (a related identifier, CVE-2026-60112, has also been assigned). It affects AIT-GUI 2.5.1 and earlier, and a fix landed in 2.5.2 on August 12, 2026. There is no report of exploitation in the wild, and the only public proof of concept is Cycode's own cross-origin demo. That is the good news. The rest of this needs your attention today if you run this console or anything built like it.

What the flaw actually does

AIT-GUI starts an HTTP server that, per Cycode, reads the host you configured and then quietly ignores it, binding to 0.0.0.0 on port 8080 regardless. An operator who set the host to localhost is actually listening on every interface. No route requires a login, and none checks a CSRF token or the request origin.

The dangerous endpoint is POST /cmd. The command field is read straight off the request, parsed, and passed to the command bus with nothing in between: no login, no allow-list, no validation. Two more endpoints, POST /seq and POST /script/run, assemble a filesystem path by gluing attacker-supplied input onto a base directory without checking that it stays inside, so a seqfile=../../../../ value climbs out of the intended folder. One of those paths then runs the referenced file as a subprocess. A correct confinement routine already lived elsewhere in the same code and was not reused.

Stated plainly: an attacker who can reach the port issues instrument commands, reads files off the host, and runs sequences from arbitrary locations, and never sees a login prompt.

A firewall does not stop this

The instinct is to say this only matters if the console faces the internet, and that instinct is wrong. Those command routes answer plain form-encoded POST bodies (the application/x-www-form-urlencoded content type), the kind a browser fires cross-origin as a so-called simple request, with no preflight to block it. So a web page an operator visits, in any tab, can POST to the console at its LAN address and the request goes through. The attacker never touches the network directly. The operator's own browser delivers the command.

That detail collapses the usual defense. "It is on an isolated VLAN" and "there is a firewall in front of it" both describe the wrong boundary. If any workstation that can route to the console also browses the web, the console is reachable through that workstation. Cross-site request forgery has always been the hole in network segmentation, and an unauthenticated command endpoint is the worst possible place to rediscover it.

The pattern: operator consoles that trust the network

This is the third self-hosted operator interface we have written up recently that failed the same way. MLflow's webhook endpoint reached the cloud metadata service through DNS rebinding and leaked instance credentials. The Ray dashboard exposed an internal-only API to the same rebinding trick. A self-hosted command tool shipped a command path with the same optimistic trust. Different vendors, different domains, one shared assumption: the network is the authentication.

It is not. A console that will act on any request it receives has no business deciding who is allowed to reach it based on where the packet came from. The point is not that NASA got it wrong. AIT-GUI is open source, the maintainers fixed it in days, and the underlying pattern is everywhere. If you run a homegrown ops dashboard, a build runner, a device manager, or any internal tool with a "we are all trusted here" posture, this is a mirror.

Why upgrading to 2.5.2 is not the whole fix

Here is the part the wire coverage buried. The 2.5.2 release does real work. It binds to the configured host instead of 0.0.0.0, adds an Origin and Referer check against the server host for state-changing methods, and confines the /seq and /script/run paths to their roots. That closes the browser-delivered attack and the path traversal. It does not add authentication. A caller that can reach the port can still open a session with no credentials and still hit the command endpoints.

Weakness2.5.1 and earlier2.5.2
Network bindIgnores config, binds 0.0.0.0Binds the configured host
Cross-origin / CSRFNo check, browser-deliverableOrigin and Referer checked
Path traversal on /seq, /script/runUnconfined pathsConfined to roots
AuthenticationNone on any routeStill none
Source: Cycode advisory GHSA-p9r8-2q67-fp86 and the AIT-GUI 2.5.2 release notes.

So "we upgraded" is not the same as "it needs a login now." If the console sits on a network any other host can reach, 2.5.2 leaves the command bus open to those hosts. The durable fix is an authenticating layer you own: put the console behind a reverse proxy that requires a login or a client certificate, bind it to localhost and reach it only over an SSH tunnel or mutual TLS, and scope who can talk to it to the operators who actually need it.

There is an operational trap on top of this. As of disclosure, the fixed 2.5.2 release exists on GitHub, but the AIT-GUI package on PyPI still shows 2.4.1 from July 2023, with no 2.5.x published at all. A team that reflexively runs pip install --upgrade ait-gui does not get the fix. You have to install from the patched source. Confirm the version you are actually running, not the one you assume the package manager fetched.

What to do now

Patch to AIT-GUI 2.5.2 from the project's source, not from PyPI, and verify the running version. Do not stop there. Bind the server to localhost, and put an authenticating reverse proxy or an SSH tunnel in front, so that reaching the port is not the same as controlling it. Hold every internal operator console you run to that standard: assume the network is hostile and require a real credential at the application, not at the firewall.

For detection, the signals are generic enough to apply to any ops console. Alert on a service listening on 0.0.0.0 where you expected localhost. Watch for POST /cmd, or your own tool's command endpoint, arriving from any source that is not loopback. Flag state-changing requests whose Origin or Referer does not match the host. Patching closes the hole. Those alerts are how you learn whether anyone walked through it before you did.

Frequently asked questions

What is the AIT-GUI vulnerability GHSA-p9r8-2q67-fp86?

GHSA-p9r8-2q67-fp86 is a critical flaw, rated CVSS 9.4, in NASA/JPL's open-source AIT-GUI operator console. It binds to every network interface with no login and no CSRF protection, so an unauthenticated request can issue instrument commands, read files, and run sequences. A related identifier, CVE-2026-60112, has also been assigned.

Is the AIT-GUI flaw being actively exploited?

No public exploitation in the wild has been reported as of disclosure. The only public proof of concept is Cycode's own cross-origin demonstration. Active exploitation is not required to treat this as urgent, because an unauthenticated command endpoint reachable from a browser is trivial to abuse once a target is known.

Which AIT-GUI versions are affected and how do I get the fix?

AIT-GUI 2.5.1 and earlier are affected, and the fix is in 2.5.2, released August 12, 2026. Install it from the project's source on GitHub. The PyPI package still lists 2.4.1 from July 2023 with no 2.5.x, so a normal pip upgrade does not pull the patched code.

Does upgrading to AIT-GUI 2.5.2 add a login?

No. Version 2.5.2 fixes the network binding, adds Origin and Referer checks, and confines the file paths, which closes the browser-delivered attack and the path traversal. It does not add authentication. A caller that can reach the port can still open a session with no credentials and reach the command endpoints.

Can a firewall or network isolation protect an unpatched AIT-GUI console?

Not reliably. The state-changing endpoints accept simple cross-origin requests, so a web page an operator visits can POST commands to the console at its internal address. If a workstation that can reach the console also browses the web, that browser can deliver the attack, which is why network segmentation alone does not contain it.

How would I detect an attack against an operator console like AIT-GUI?

Alert when a service listens on 0.0.0.0 where you expected localhost. Watch for POST requests to the command endpoint from any source that is not loopback, and flag state-changing requests whose Origin or Referer header does not match the host. These signals generalize to any internal operator dashboard, not just AIT-GUI.

Ready to meet the Guardians?

Deploys fast - agentless for monitoring and cloud, a lightweight agent for deep endpoint security. Just Suriq, standing watch.