AI infrastructure security testing means testing the HTTP services in an AI stack, the MCP servers, model gateways, inference interfaces and orchestration dashboards, the same way you already test an application: at the deployed address, with a real request and a real response. The published advisories in this layer are not AI vulnerabilities. They are web vulnerabilities in software nobody put in scope.
Read the published advisories in the AI tooling layer and a pattern shows up immediately. Not one of them involves the model. Not one of them involves a prompt. They involve a bind address, a request header, and a route that answers without asking who is calling.
Key takeaways
- Three advisories in AI infrastructure resolve to a listener bound to every interface, a request header reaching a server-side fetch, and an unauthenticated route returning credentials in cleartext.
- None of them concern the model, the prompt, or a dependency version. All three are properties of a running HTTP service.
- Internet-wide scans found MCP services in the tens of thousands. In one study, every manually verified server answered a tool listing with no authentication at all.
- The failing control lives in the listener configuration and the middleware chain in front of the route. Neither appears in a specification, a model card, or a dependency inventory.
- This layer is missed for a scope reason, not a technical one. It gets deployed by people who do not own the application inventory.
Three advisories, no AI in any of them
The MCP server that answers everyone
The advisory for argocd-mcp 0.8.0 carries a CVSS score of 10.0 and is fixed in 0.9.0. It is really three defects stacked in one transport: the server accepts environment credentials on behalf of unauthenticated requests, it does not validate the Host and Origin headers, and it listens on 0.0.0.0 by default.
Put together, a caller who can reach the port opens an MCP session and drives the entire tool surface using the operator's stored Argo CD token. The advisory describes the outcome plainly: an attacker can create applications sourced from a repository they control and trigger a sync, deploying attacker-controlled Kubernetes manifests with no authentication and no user interaction.
Notice the shape of it. The dangerous capability was intentional. The tools are the product, and deploying manifests is exactly what they are for. What failed was the ordinary question of who is allowed to call them, answered one layer below anything the protocol has an opinion about.
The gateway that forwards a header
CVE-2025-66405 describes a gateway that chose its destination base URL from an incoming request header, x-portkey-custom-host, appended the client-supplied path, and fetched the result. That is server-side request forgery. Point it at an internal service, or at a cloud metadata endpoint, and the gateway retrieves it using the network position it has and the caller does not. The advisory names data exfiltration through the AWS metadata service as the example. The fix, in 1.14.0, is an allow-list of trusted hosts.
A request header flowing unvalidated into a server-side fetch is one of the oldest findings in the web application catalogue. Here it lands in a product whose entire job is to sit in front of a model and forward traffic.
The route that hands back the password
CVE-2026-82288 covers Stable Diffusion WebUI through version 1.10.1 and scores 8.7 on CVSS v4.0. The /sdapi/v1/cmd-flags route returns the process's parsed launch arguments in cleartext, and those arguments include --gradio-auth and --api-auth: the credentials configured to protect the interface. An unauthenticated caller reads the password out of the API and then logs in with it.
The detail worth sitting with is that the same application already knows how to do this correctly. Its /internal/sysinfo endpoint redacts sensitive fields. One route got the filter and one did not, which is a per-route property, invisible from anywhere except the route itself.
What the three have in common
None of these is a model problem, and no amount of adversarial prompting would surface any of them. Strip the AI framing away and you are left with three findings that would be unremarkable in a 2015 penetration test report:
- A listener bound too widely. The service decided who could reach it before any application logic ran.
- Untrusted input reaching a server-side request. The service used a caller-supplied value to choose where to send traffic.
- A route with no authentication and no output filtering. The service answered a question it should have refused, and told the truth in the response.
Every one of those controls is a property of a running HTTP service. You can hold the source code and still not know the answer, because the answer depends on how the thing was started and what sits in front of it.
Why this layer slips out of scope
The reason is not that these bugs are hard. It is that this software has different provenance from the rest of the estate. It arrives as a package install or a container image rather than as a repository your team owns. It is stood up by platform engineers or data scientists solving a delivery problem. It runs on an internal network somebody has decided is safe. And so it never gets entered into the application inventory that scanning, testing and review are pointed at.
The exposure data suggests the internal-network assumption is doing a lot of unearned work. Censys began scanning for MCP services on April 24, 2026, and counted 12,520 internet-accessible MCP services across 8,758 unique IP addresses four days later. By May 6 the figure had passed 21,000. Their own note on the set is that "at a minimum, the servers discussed throughout this blog were accessible without authentication."
Knostic ran a narrower and more pointed experiment. Their survey of exposed MCP servers fingerprinted 1,862 of them, then manually verified a sample of 119 by issuing a read-only tools/list request, the protocol equivalent of asking a service what it can do. All 119 answered without authentication.
Neither team needed an exploit. Both simply asked, over the network, and read what came back. That is the same act a scanner performs, and it is the act that nobody had performed against these services before.
The default is the finding
Binding to 0.0.0.0 is not carelessness. It is the setting that makes a service work inside a container, and it is usually written by whoever needed the thing to start, not by whoever owns the consequences of it being reachable. The same is true of enabling an API flag without the matching auth flag. These are convenience defaults that quietly encode an access-control decision.
That is also why reading the configuration is not the same as knowing the answer. A manifest can specify a loopback bind and a network policy and still describe a service that a neighbouring workload can reach. The file states an intention. The deployed instance states a fact, and the only way to collect the fact is to send it a request from where an attacker would stand.
What each approach actually proves
| Approach | What it establishes | Where it stops |
|---|---|---|
| Dependency and container scanning | That a component with a published advisory is present in the build | Says nothing about whether the service is reachable, or whether a given route enforces anything |
| Model and prompt evaluation | How the model behaves under adversarial input | Says nothing about the transport carrying the input, which is where all three advisories live |
| Configuration and manifest review | The intended bind address, auth flags and network policy | Cannot confirm the deployed instance matches the file, or that a route implements what the file implies |
| Dynamic testing at the deployed address | Which routes answer, to whom, and what comes back in the response | Only covers the addresses it was given |
The last row is the honest one, and it is also the whole problem. Dynamic testing settles these questions cleanly, but only for services somebody remembered to list. This class of service is precisely the one nobody lists.
The address list is the work
Which makes the fix less technical than it sounds. There is no separate discipline to invent here, and treating AI infrastructure as a special security category is arguably how it got skipped in the first place. An MCP server is a web server. A model gateway is a reverse proxy with opinions. An inference interface is a web application with a REST API attached. Each one either answered a request or it did not, and finding out is the same act it has always been.
That is the whole of NightVision's position on this, and it is deliberately unremarkable. It tests running web applications and APIs at their deployed address, fully authenticated, from CI, and returns the complete request and response for every finding so the result reproduces exactly rather than arriving as a label somebody has to re-derive. For the applications your teams write, it derives the endpoint list from source rather than from a specification that was maintained by hand and has drifted since.
For the AI services your teams deploy but did not write, the ask is smaller and entirely procedural: get their addresses onto the same list as everything else. The three advisories above were all found by someone who did.
The model was never the attack surface here. The listener was, and it had been answering the whole time.
Related readingPart of our series on modern application security testing. Start with What You Should Know About Application Security Testing, then read MCP Server Security Testing on what an MCP deployment exposes, and Reverse Proxy Access Control Testing on access rules that live in front of your code.
Frequently asked questions
Is AI infrastructure security testing different from application security testing?
In practice, no, and assuming otherwise is what causes the gap. The services in an AI stack are HTTP servers with routes, authentication, input handling and output filtering. The published advisories in this layer are ordinary web findings: a listener bound to every interface, a header reaching a server-side fetch, an unauthenticated route disclosing credentials. What is different is ownership and inventory, not technique.
What is an MCP server, in security terms?
It is a network service that exposes a set of callable tools to a client, typically over HTTP, usually holding credentials for the systems those tools operate on. Security-wise that makes it a privileged API with a tool listing that describes its own capabilities. The interesting questions are the standard ones: what address does it listen on, does it authenticate the caller, and whose credentials does it act with when it does not.
Do these bugs require the attacker to be authenticated?
In all three cases above, no. That is what pushes them to critical and high severity. The argocd-mcp advisory describes tool execution with no authentication and no user interaction, the gateway forgery is driven by an ordinary request header, and the credential disclosure route answers unauthenticated callers whenever the API auth flag is not set.
Does dependency scanning catch this class of bug?
Only after the fact, and only for the specific package. A dependency scanner can tell you that a vulnerable version is present once an advisory exists and your inventory includes the component. It cannot tell you whether your instance is reachable, whether a route enforces authentication, or whether your own wiring introduced the same class of flaw. Those are runtime properties, not build-time ones.
Where should an AI stack's HTTP services appear in an inventory?
In the same inventory as every other application, with an owner and a deployed address. The practical test is whether the service has a URL that something in your environment can resolve and connect to. If it does, it belongs on the list that testing is pointed at, regardless of whether the network it sits on is described as internal.
If we red-team the model, do we still need to test the transport?
Yes, and they answer unrelated questions. Model evaluation tells you how a system behaves when the input is hostile. It cannot tell you that the service accepting that input is reachable from the internet, or that a sibling route returns the credentials protecting it. Both of those were real findings, and neither would surface from any prompt.