One Forged Header: Unauthenticated Authentication Bypass in Fortinet FortiClient EMS (CVE-2026-35616)
Vulnerability Overview
Fortinet has disclosed a critical authentication bypass affecting FortiClient Endpoint Management Server (EMS). Tracked as CVE-2026-35616 and carrying a CVSS score of 9.1, the flaw lets a remote, unauthenticated attacker bypass the EMS API's certificate-based authentication and issue privileged requests as if they were a trusted administrator. From that position an attacker can execute unauthorized code or commands and reach the endpoints EMS manages. The vulnerability was exploited in the wild before Fortinet published its advisory, and CISA added it to the Known Exploited Vulnerabilities catalog on April 6, 2026.
If you run FortiClient EMS 7.4.5 or 7.4.6 without the hotfix applied, treat the server as compromised until proven otherwise. This was a zero-day, so patching alone is not a complete response.
Why FortiClient EMS Is a High-Value Target
FortiClient EMS is the central management plane of a Fortinet endpoint deployment. Organizations use it to push security policies, manage VPN profiles, enforce compliance posture, and control FortiClient agents across the entire fleet from one console. That central position is exactly what makes a flaw here so dangerous: as watchTowr noted, a compromised EMS server gives an attacker the ability to manipulate endpoint configurations, push malicious policies, and pivot laterally into the wider environment. You are not just losing one server - you are losing the system that governs all the others.
Technical Analysis
The clearest breakdown of the root cause comes from Bishop Fox, who reverse-engineered the flaw from Fortinet's hotfix. It is a textbook trust boundary violation built on two compounding mistakes.
First, the Django application behind EMS reads client-certificate information from HTTP headers - specifically X-SSL-CLIENT-VERIFY and X-SSL-CLIENT-CERT - and treats them as equivalent to the WSGI environment variables that Apache's mod_ssl normally populates. In a correct setup those headers would only ever be set internally by the reverse proxy after a genuine TLS client-certificate handshake. But the Apache configuration shipped with EMS never strips them from inbound requests, so a value an attacker types into a header travels all the way to the application and is trusted as if it came from the proxy.
Second, the certificate validation that follows is hollow. According to Bishop Fox, the certificate-chain check performs only string matching on the Distinguished Name (subject/issuer), with no cryptographic signature verification. An attacker therefore does not need a legitimately signed certificate - they can forge one whose DN strings match what the server expects.
Put together, the exploit collapses to almost nothing. Researchers including Kerem Atın demonstrated that injecting a single header - X-SSL-CLIENT-VERIFY: SUCCESS - into a request to an EMS API endpoint flips the server from unauthenticated to fully authenticated administrator. No brute force, no credential stuffing, no user interaction.
Active Exploitation in the Wild
This is not theoretical. watchTowr's sensors detected exploitation on March 31, 2026 - days ahead of Fortinet's April 4 advisory - meaning attackers were already inside affected environments at disclosure. Cybersecurity Dive reported that the Shadowserver Foundation flagged active abuse, and noted this was the second unauthenticated FortiClient EMS bug in a matter of weeks, landing over the Easter holiday weekend when response teams were thin.
Arctic Wolf documented a full intrusion chain built on this CVE. After bypassing authentication, the threat actor abused EMS's trusted position to push malware to managed endpoints, disguising a credential stealer as a Fortinet update. The payload - delivered as FortiEndpoint_Patch.exe and executed silently through PowerShell - is a MinGW-compiled Windows infostealer Arctic Wolf calls EKZ, capable of extracting saved credentials from Chrome and Firefox, including techniques to defeat Chrome's encrypted password storage. Malware masquerading as the patch for the very vulnerability used to deliver it is a detail worth flagging to defenders.
Detection
Several researchers have published safe, non-destructive detection scripts that use differential response analysis. The technique sends a baseline request with no special headers - a patched or unaffected server returns HTTP 401 - then sends the identical request with X-SSL-CLIENT-VERIFY: SUCCESS injected. If the status code changes (typically to 500 or 200), the middleware is trusting the spoofed header and the host is vulnerable. No exploit payload is sent. Bishop Fox's checker is a good starting point and relies only on the Python standard library.
The hotfix adds Apache RequestHeader unset directives that strip X-SSL-CLIENT-VERIFY and X-SSL-CLIENT-CERT before they reach Django, so a fully patched server returns an identical 401 to both probes.
Affected Versions & Fixes
| Product | Affected | Resolution |
|---|---|---|
| FortiClient EMS 7.4.6 | Vulnerable | Apply out-of-band hotfix; upgrade to 7.4.7 when available |
| FortiClient EMS 7.4.5 | Vulnerable | Apply out-of-band hotfix; upgrade to 7.4.7 when available |
| FortiClient EMS 7.4.7 | Not affected | Contains the permanent code-level fix |
Mitigation & Remediation
Priority order, drawn from Fortinet's advisory (FG-IR-26-099) and NetSPI's remediation guidance:
- Patch immediately. Apply Fortinet's out-of-band hotfix for 7.4.5 and 7.4.6 now. The permanent, code-level fix - which also addresses the string-only certificate validation - ships in FortiClient EMS 7.4.7, so move to that release as soon as it is available rather than treating the hotfix as the finish line.
- Get it off the internet. Restrict access to the EMS administrative interface to trusted IP ranges. There is no good reason for this console to be directly reachable from the public internet.
- Add WAF coverage. Block anomalous HTTP header injection patterns at the edge as a defense-in-depth layer.
- Hunt for compromise. Monitor EMS for unexpected child processes such as
cmd.exeorpowershell.exe, review managed endpoints for the EKZ indicators Arctic Wolf published, and verify the patch took by re-running a safe header-spoofing check.
The Bigger Picture
CVE-2026-35616 did not arrive alone. It followed CVE-2026-21643, an unauthenticated SQL injection (CWE-89) in FortiClient EMS 7.4.4 that was also exploited in the wild and whose fix path was to move to 7.4.5 or above. Two unauthenticated, actively exploited bugs in the same management product within weeks is a strong signal that internet-facing endpoint management infrastructure deserves the same scrutiny - segmentation, monitoring, and rapid patch discipline - you would give any crown-jewel system. When a flaw lands in a management server, the question is not only whether an attacker can get in, but what authority that system holds and what it touched.
References
- Fortinet PSIRT - FG-IR-26-099
- NVD - CVE-2026-35616
- CISA - KEV Catalog Addition (2026-04-06)
- Bishop Fox - API Authentication Bypass Root-Cause Analysis
- watchTowr - Active Exploitation Underway
- Arctic Wolf - EKZ Infostealer Campaign
- NetSPI - Overview & Remediation Takeaways
- Cybersecurity Dive - Critical Flaw Under Exploitation
- Bishop Fox - Non-Destructive Detection Script