FortiClient EMS manages endpoints. It holds the inventory, the policies, and the remote access profiles for every device an organization has enrolled. In March 2026 attackers reached one over the internet, authenticated as nobody, and used it to install an infostealer on the endpoints it managed. The file was called FortiEndpoint_Patch.exe.
The vulnerability needed no credential. It needed a management server that would accept the connection.
What actually happened
CVE-2026-35616 is an API authentication bypass in FortiClient EMS 7.4.5 and 7.4.6, rated CVSS 9.1. Bishop Fox found the mechanism, and it is worth stating precisely because the failure is not subtle.
The authentication middleware checks whether a client certificate was verified. It reads two places: SSL_CLIENT_VERIFY, a WSGI variable Apache sets and a caller cannot, and HTTP_X_SSL_CLIENT_VERIFY, which is Django's automatic mapping of the X-SSL-CLIENT-VERIFY request header. Anyone can set the second one. The code preferred it.
So an attacker sends X-SSL-CLIENT-VERIFY: SUCCESS and an X-SSL-CLIENT-CERT header holding a certificate chain. The chain is then validated by string matching the distinguished names, with no signature verification at any point, and the Fortinet root CA distinguished names are extractable from publicly downloadable FortiClient packages. A self-signed certificate with matching name strings passes.
That granted certificate-user privileges across sixteen endpoint definitions: device quarantine and command execution, server reconfiguration, JWT secret rotation, ZTNA private key access, and full inventory export.
| Date | Event |
|---|---|
| 31 March 2026 | Exploitation in the wild reported to Fortinet |
| 6 April 2026 | Added to the CISA Known Exploited Vulnerabilities catalog |
| 7 April 2026 | Bishop Fox publishes the technical mechanism |
| May 2026 | Arctic Wolf observes the delivery campaign |
Arctic Wolf reconstructed what the access was used for, and this is the part that separates the incident from an ordinary appliance compromise. The attackers did not stop at the server.
They changed two settings. First remind_upgrade_after, to suppress the firmware reminders that would have prompted somebody to apply the fix. Then the Remote Access Profile, to inject a script.
FortiClient runs scripts when an endpoint establishes its IPsec tunnel. So every managed device that connected to the corporate VPN executed base64-encoded PowerShell, which downloaded a four megabyte binary named FortiEndpoint_Patch.exe. It read saved passwords, cookies and autofill data from Chrome, Edge, Chromium and Firefox, staged the results in C:\ProgramData\log.txt, and posted them to an address the attackers controlled.
The security tool did not fail to stop the malware. It delivered it.
The gap: the console authenticated after it answered
Every control in this story was positioned behind an authentication event that never happened.
- Certificate authentication was the control, and it was the thing bypassed. The middleware asked whether a certificate had been verified rather than verifying one.
- The VPN scripting feature worked exactly as designed. Running a script on tunnel establishment is a legitimate management capability. It was executed by an administrator the system believed in.
- Endpoint protection saw a signed management channel. The instruction came from the organization's own console, over its own VPN, to agents configured to take instructions from it.
- The name did the rest. A file called FortiEndpoint_Patch.exe arriving through Fortinet tooling, at a moment when a Fortinet advisory was live, reads as compliance rather than compromise.
There is a harder version of this to sit with. The attackers suppressed the upgrade reminders first. The signal that would have told an administrator to patch was turned off using the same access that made patching urgent.
What would have had to be true
For the forged header to fail, it would have had to arrive somewhere that did not answer it.
That is a narrower claim than it sounds, and it is worth keeping narrow. The bypass is a code defect, and code defects are fixed by the vendor's patch. Fortinet issued a hotfix and a fixed release, and applying it is the remediation. runZero's guidance on this vulnerability is to upgrade, and that is right.
The distinction is about the interval. Exploitation was reported on 31 March. The mechanism was public on 7 April. The campaign Arctic Wolf documented ran into May. Through all of that, an EMS management server reachable from an arbitrary network could be given a forged header by anyone who had read the write-up. A server that answered only known administrative origins could be given one by a much smaller set of people.
Neither state removes the vulnerability. They differ in who gets to reach it during the weeks before the fix lands.
Where Veribound would have fitted
Veribound is a pre-session edge access control platform, and an intelligence layer. It does not patch FortiClient EMS, inspect VPN scripts, evaluate PowerShell, or replace endpoint protection.
Agents attest that devices are still trusted. The trust-scoring engine turns those attestations into per-device decisions. What reaches the customer's existing edge is a trusted origin: the network a trusted device is connecting from. Those origins are kept current in the address groups the customer's own policy already references.
Applied to an internet-reachable endpoint management console:
- The customer's own edge answers only trusted origins, so an unrecognized network does not get to present
X-SSL-CLIENT-VERIFY: SUCCESS. - The CVE remains critical, and Fortinet's fix remains required.
- Administrative access keeps using the existing Fortinet and identity controls. Those controls meet a smaller population of connections.
- An administrator working from a new network does not require permanently widening the management rule, because the trusted origin moves with the trusted device.
What it would not have done. It would not have removed the injected script from the Remote Access Profile, recovered the credentials already exfiltrated, or stopped an attacker operating from a device and network the organization already trusted. It would not have helped at all in an architecture where the management console has no edge in front of it capable of restricting source networks.
The lesson in FortiEndpoint_Patch.exe is not that endpoint management needs another authentication layer. Authentication was the layer, and it was answered by the attacker's own header. The earlier question was whether a console that can run code on every managed device needed to answer the whole internet while its patch was pending.
Source: FortiClient EMS Exploited via CVE-2026-35616 to Deliver EKZ Infostealer Disguised as a Fortinet Patch, Arctic Wolf, May 2026, and API Authentication Bypass in FortiClient EMS 7.4.5-7.4.6, Bishop Fox, 7 April 2026.