← Back to Attack Research

The agent that disabled its own certificate checks: hardcoded insecure TLS and vCenter credential theft

You install an agent to help migrate your virtual estate. It connects to vCenter with certificate validation switched off, hardcoded, with no way to turn it on. An attacker on the same network segment intercepts that connection and walks away with your vCenter administrator credentials. CVE-2026-53475, rated CVSS 9.3, is exactly this. Here is the attacker decision tree, why your version scanner reports nothing, and the fix.

The tool you trust to manage the estate became the door into it. An assisted-migration agent, the kind of helper you deploy to move workloads into a Kubernetes-managed environment, hardcoded an insecure TLS configuration when it talked to vCenter. Certificate validation was disabled in the connection code, with no operator switch to re-enable it. An attacker positioned on the same network segment intercepts the agent's TLS session, presents a certificate the agent never checks, and captures the vCenter administrator credentials the agent sends across that session. CVE-2026-53475, disclosed with Red Hat as the assigning authority and rated CVSS 9.3, is the latest reminder that a management agent is a credential conduit, and a conduit that skips certificate validation is a credential leak.

This is the companion to our hardcoded signing keys piece, and it is the other half of the same disease. That post was about hardcoded secrets: a key shipped in the artifact that anyone can read. This one is about hardcoded trust settings: a security decision shipped in the artifact that nobody can change. The first hands the attacker a credential directly. The second tears down the wall that was supposed to keep credentials from being intercepted in transit. Both are properties of what shipped, not behaviors of the running service, and both hide from the scanners most teams rely on.

The relevant weakness is CWE-295 (Improper Certificate Validation): the product does not validate, or incorrectly validates, the certificate presented by the host it connects to. When a TLS client skips that check, the encryption is still there, but the authentication is gone. You have a private channel to whoever answered, and you have no idea who answered. That is precisely the gap a man-in-the-middle needs. Verifiable security.

The class in one paragraph

TLS does two jobs at once. It encrypts the channel, and it authenticates the peer by validating the certificate the peer presents against a trusted chain and the expected hostname. Disable the second job and the first becomes theater. A client that connects with InsecureSkipVerify: true, verify=False, a custom trust-everything callback, or any equivalent will happily complete a handshake with an attacker who terminates the connection in the middle, presents any certificate at all, and forwards the traffic onward. The encryption protects the attacker's interception as faithfully as it would have protected the real endpoint. When the client then sends credentials over that channel, as a management agent must in order to log in to what it manages, the attacker reads them in cleartext on their side of the proxy. The defining property is that the insecure choice is baked into the agent. The operator cannot harden it, because the validation was never wired to a setting. It is hardcoded off.

CVE-2026-53475 is the textbook instance. The affected component is an assisted-migration agent in a Kubernetes virtualization migration toolchain, the kind of agent an operator installs to inventory and move virtual machines out of a vSphere estate. To do that work it authenticates to vCenter, the management plane of the entire virtual environment. The agent hardcodes an insecure TLS connection to vCenter: certificate validation is disabled in code rather than gated behind a flag the operator controls. An attacker with a position on the network path between the agent and vCenter, an adjacent-network attacker rather than a remote one, intercepts the TLS session and obtains the vCenter administrator credentials the agent transmits. With vCenter administrator credentials, the attacker controls every host, every virtual machine, every datastore, and every snapshot in the estate. The blast radius is the whole virtual environment.

Why this hides from your scanners

The reason hardcoded insecure TLS persists is that the controls most teams rely on are structurally blind to it.

  1. Version and CVE-by-banner scanning miss it. The agent is running the exact version it claims to be. Nothing about the version string reveals that one connection inside the agent skips certificate validation. Two installs of the identical build behave identically, because the insecure choice is not a deployment option, it is the only behavior. A version match cannot surface a flaw that is uniform across every copy of that version.
  2. Runtime DAST sees an agent that works. A dynamic scanner watches the agent connect to vCenter, complete a TLS handshake, authenticate, and do its job. From the outside it is a healthy encrypted session. The scanner has no privileged view of whether the client validated the server certificate, and in the common case where nobody is actively intercepting at scan time, there is simply nothing anomalous to observe. The vulnerability is a missing check, and a missing check produces no signal until someone exploits it.
  3. The insecure line is in code nobody re-reads. A single TLS client option set during early development, when the test vCenter used a self-signed certificate and disabling validation was the quick way to make the integration work, survives into the shipped product. The comment that said fix before release is gone. The reviewer who would have caught it saw a working migration and approved it. The setting is one boolean in one client constructor, buried in an agent that does a hundred other things.

Detecting this class requires inspecting the agent's configuration and connection code, not probing the agent from the network. You have to read how it builds its TLS client. That is the entire point.

The attacker decision tree

ATTACKER DECISION TREE Hardcoded Insecure TLS in a Management Agent ┌──────────────────────────────────────────┐ │ 1. Get a position on the path │ │ - same VLAN / network segment │ │ - ARP / DHCP / rogue gateway │ │ - compromised switch or hop │ │ - the agent and vCenter share a LAN │ └──────────────┬───────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ 2. Intercept the agent -> vCenter TLS │ │ - terminate the session in the middle│ │ - present ANY certificate │ │ - the agent does not validate it │ │ - handshake completes anyway │ └──────────────┬───────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ 3. Harvest credentials in cleartext │ │ - read the vCenter login the agent │ │ sends over the channel you proxy │ │ - admin username + password / token │ └──────────────┬───────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ 4. Authenticate to vCenter as admin │ │ - replay the captured credentials │ │ - now you are the management plane │ └──────────────┬───────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ 5. Own the virtual estate │ │ - every host, VM, datastore, snapshot│ │ - clone, exfil, encrypt, pivot │ └──────────────────────────────────────────┘

No exploit code. The attacker only has to be on the path and present a certificate the agent was built never to check.

The decisive feature is step 2. The attacker does not break TLS, guess a password, or trigger a memory bug. They present a certificate, any certificate, a self-signed one minted thirty seconds earlier, and the agent accepts it because validation was hardcoded off. Everything after that is ordinary credential capture over a channel the attacker controls. This is why CWE-295 is rated high-likelihood-of-exploit: once the client refuses to authenticate the server, interception is deterministic for anyone who can get on the wire. The attack requires adjacency rather than a remote network position, which is the one mercy here, but adjacency is cheap inside a flat datacenter VLAN, a shared management network, or any environment where the agent and vCenter were never segmented from each other.

The class is everywhere, not just one agent

Disabled certificate validation is one of the most common real-world TLS failures, and it spans every kind of client. The shape is always the same: a developer turned off validation to get past a certificate error during integration, and the override shipped. A close relative is CWE-297 (Improper Validation of Certificate with Host Mismatch), where the chain is checked but the hostname is not, so a valid certificate for the wrong host sails through. Both leave a man-in-the-middle unauthenticated and undetected. The history of TLS is full of the broader lesson that an unauthenticated or downgradeable channel is an interceptable one: CVE-2014-3566 (POODLE) showed a man-in-the-middle forcing a downgrade and reading cleartext, and the defensive response was always to authenticate the peer and refuse the insecure path. The migration agent simply removes that authentication entirely.

The variants share a single shape:

What we observe

We are honest about the limits of our visibility. CelvexGroup's continuous validation runs against assets and software the customer flags into scope, and the always-safe lane we operate is passive recon, version reads, and configuration and source inspection rather than active interception of live management traffic. We do not set up a man-in-the-middle against a customer's production vCenter to prove the point. Within that scope, inspecting how agents and integrations are configured to make their outbound TLS connections, the pattern is consistent: certificate validation gets disabled during integration and never gets turned back on, because the connection works either way and nothing in the pipeline forces the question. A management agent that authenticates successfully raises no alarm. The single line that would have made it validate the server is almost always optional in the code, and therefore almost always left off.

What to do about it: the trust contract

Hardcoded insecure TLS is a build-time and configuration problem, so the controls live there. We summarize them as a contract every client that opens a TLS connection should satisfy.

TLS trust contract: six controls that end the class

Encryption without authentication is a private line to a stranger. If the agent will not check who answered, the attacker only has to answer first.

The detection grep, in concrete terms, is to hunt the disable-validation idioms across the agent's source and its dependencies:

# Go: the classic disabled-validation flag
$ grep -rn "InsecureSkipVerify" --include="*.go" .

# Python: requests / urllib3 / ssl with verification off
$ grep -rnE "verify\s*=\s*False|CERT_NONE|check_hostname\s*=\s*False" \
    --include="*.py" .

# Java / JVM: trust-all managers and null hostname verifiers
$ grep -rnE "X509TrustManager|ALLOW_ALL_HOSTNAME_VERIFIER|TrustAllCerts" .

# CLI and config: permanent --insecure / skip-tls flags
$ grep -rnE "insecure[-_]?skip|--insecure|skip[-_]?tls[-_]?verify" .

Read each hit. Confirm validation is on by default and that any relaxation is behind a guarded operator flag, not a hardcoded constant. For an agent that authenticates to a management plane, confirm there is no relaxation path at all. The exercise is finishable in an afternoon for any agent, and it is the only way to find this class, because the running agent will keep authenticating successfully and tell you nothing.

How Celvex catches this

Find. Prove. Fix. Verify.

Find

We inspect the configuration and connection code of agents and integrations in scope, hunting the disable-validation idioms and the hardcoded trust settings that let an agent open a TLS session it never authenticates.

Prove

For a confirmed hardcoded insecure TLS path, we ship a signed Proof Capsule with the exact file and line, the disabled-validation construct, and an authorized lab demonstration that an unrelated certificate is accepted on the agent's own out-of-band test path.

Fix

The Capsule's remediation block points at the trust contract: remove the override, pin or scope the trust anchor, move to mutual TLS for control-plane links, and add the CI grep that fails the build on a hardcoded disable.

Verify

After the fix lands, the agent rejects a certificate it should not trust and the CI gate is green. The finding closes automatically and the verified-fix event is recorded for the auditor.

This sits squarely in the cloud and infrastructure validation lane, where the evidence is how a component is configured to connect rather than a live interception of production traffic. Our cloud security validation capability is built for exactly this: proving a property of how an agent or integration trusts the management plane, signing the proof, and letting the customer reverify it independently. We do not claim to mount a man-in-the-middle against your production vCenter. We do claim that when an agent in scope opens a TLS connection with validation hardcoded off, we find it, prove it with a reproducible Capsule, and verify the fix held.

Bottom line

The agent you install to manage your infrastructure is a credential conduit, and a conduit that skips certificate validation is a credential leak. CVE-2026-53475, rated CVSS 9.3, is the clean example: an assisted-migration agent hardcodes an insecure TLS connection to vCenter, so an attacker on the same network segment intercepts the session, presents any certificate at all, and harvests the vCenter administrator credentials, which is to say the keys to the entire virtual estate. Your version scanner reports the correct version. Your runtime DAST watches a healthy encrypted session. The insecure line is one boolean in one client constructor that nobody re-reads. This is the other half of the hardcoded-secrets story: not a key in the box, but a trust setting nailed to off. The fix is not clever. Validate by default, never ship an insecure default the operator cannot change, pin or scope trust, prefer mutual TLS to the management plane, and grep your TLS clients in CI. The audit is an afternoon. Until that afternoon, every agent that skips the check is one adjacent attacker away from your control plane.

Verifiable security. Find it. Prove it. Fix it. Verify the fix held. That is what we ship.

Sources

Find the disabled check before someone else does.

Free Exposure Check, no signup required. We inspect the agents and integrations in your footprint for hardcoded insecure TLS, and ship a Proof Capsule for the highest-confidence finding.

Run a Free Scan →