Zero-Day FortiMail CISA KEV

A null byte in the FortiMail IBE path writes anything

October 5, 2026·8 min read·Chris Boker, Founder, CVEasy AI
A dark attacker tile on the left holds an HTTP POST request whose path contains gold dot dot slash sequences and a bold gold NUL marker in front of a mint dot cgi suffix, a rust dashed curve carries the request past a mint suffix check gate marked with a gold bypass ring and lands on a central gold FortiMail appliance panel showing a webshell file dropped at slash data slash bin slash webconsole, green arrows fan out from the appliance to right side rails representing mail queues and archived mailboxes, and a gold KEV clock sits in the upper right

Your FortiMail appliance speaks HTTPS on port 443 so administrators can log into the GUI and so remote recipients can pick up encrypted messages. Among the many handlers in that web stack is one named Identity-Based Encryption, a feature most of your users probably never touch and most of your admins forget is even reachable. On October 1, 2026, Fortinet quietly admitted that someone had been talking to that handler for weeks. The advisory is FG-IR-26-175, the identifier is CVE-2026-104286, the score is 9.8, and there is no patch yet.

The request Fortinet quietly described

The advisory names two weaknesses in the same request handler: CWE-22 path traversal and CWE-158 improper neutralization of a NULL byte. The vulnerable code lives inside the Identity-Based Encryption module, exposed through the FortiMail web interface on the same port as the admin UI and the webmail. CISA added the CVE to the Known Exploited Vulnerabilities catalog the same day, with a federal remediation deadline of October 4, 2026, three days after disclosure.

One unauthenticated HTTP request to that handler, with a crafted file path containing both ../ sequences and an embedded %00, lets the attacker write a file of their choosing anywhere on the appliance. No credentials, no session, no prior foothold. On a default FortiMail configuration, the entire sequence from first byte on the wire to a live root-level shell runs in under two minutes.

Where the null byte lands in the string

The IBE handler expects to write a message or key file into a controlled directory with a controlled extension. Before writing, the code checks the suffix of the path it was given so an attacker cannot drop a script where only data belongs. That suffix check is written against the C string the handler received, and C strings terminate at the first null byte.

So the attacker sends a path that looks like ../../../../data/bin/webconsole%00.cgi. The validation routine walks the characters, finds .cgi at the tail, and accepts the write. The underlying filesystem call then receives the same bytes and stops at the null, so the file that actually lands on disk is ../../../../data/bin/webconsole. Two parts of the same program read the same input and get different answers because they disagree on where the string ends. That gap is the whole vulnerability.

Path traversal on its own would be caught by the extension check. The extension check on its own would be a reasonable guardrail. The pair fail together, which is the shape of a class the industry has been rediscovering since CVE-2007-4517 and CVE-2010-2333. Any time a safety check and a sink parse the same bytes with slightly different rules, someone will eventually drive a wedge through the gap.

From one write to root in under two minutes

Writing one file is the whole exploit, because FortiMail hands code execution to any file in the right place. Field reporting on the first wave describes operators dropping a webshell at /data/bin/webconsole, which the appliance's web dispatcher executes as a CGI, giving the attacker an interactive shell as the web user. From there, two further writes build persistence: a malicious binary at /bin/smit and a modified /data/bin/mailservice, both executed by the appliance on normal mail delivery paths. The webshell can be removed, incident response can reinstall the GUI, and the attacker still has code on the box the next time mail flows.

Because the write runs before authentication, every FortiMail with the management interface reachable from the public internet is exposed in the default IBE configuration. The Shodan surface for FortiMail is in the tens of thousands of appliances, and runZero's edge enumeration consistently finds a majority of them with the web interface wide open. Fortinet's advisory lists the affected versions as FortiMail 8.0.0 through 8.0.1, 7.6.0 through 7.6.6, 7.4.0 through 7.4.8, and 7.2.0 through 7.2.9. Fixed builds are planned in 8.0.2, 7.6.7, and 7.4.9. None of those builds shipped on disclosure day.

What's on the appliance: FortiMail holds the full archive of inbound and outbound mail, DKIM private keys, LDAP bind credentials for the directory it integrates with, S/MIME certificates, and the IBE keys themselves. A webshell on this appliance is a tap on the mail stream, a credential store, and a lateral movement foothold into the directory.

Where scanners and CVSS slip on this

A CVSS-first queue reads 9.8 and files this under "patch now", which is exactly the direction you need to go until you notice that no patch exists. The scanner equivalents of that queue scrape version banners from the FortiMail login page and emit a finding keyed to the fixed version string that was not released yet. The finding then sits in a bucket for the next scan window because nothing in the queue says "the fix is to disable a feature, not to upgrade a build". That is a routing error, not a severity error, and it costs you the window during which active exploitation is spreading.

The second miss is subtler. IBE is on by default on every build in the affected range, but a healthy fraction of FortiMail deployments never actually use it, which means the mitigation of disabling the feature has zero business impact for those environments and should sit higher in the queue than any patch workflow. A tool that ranks mitigation strictly below patching reorders those environments wrong. The appliance ships with the vulnerable surface exposed whether the organization intended to accept the risk or not.

TRIS layers that decide this one in your inventory

TRIS, the Threat and Risk Intelligence Scoring engine inside CVEasy AI, scores each finding across layers that the single CVSS number compresses away. For CVE-2026-104286 four of those layers decide the number.

Exploitation status. Fortinet confirmed in-the-wild exploitation at disclosure, and CISA added the CVE to KEV on the same day with a three-day federal deadline. TRIS pulls both signals into the top band. Not every proof of concept counts as in-the-wild abuse, but Fortinet's own PSIRT language and the KEV listing together make this one.

Attack path. Pre-auth, single HTTP request, no interaction. The exploit text is short enough to fit in a scanner payload. TRIS weights an unauthenticated single-request chain above the same bug behind a login, because the mean time to first touch after disclosure is counted in hours rather than days.

Real exposure. This is where the same CVE scores differently across your inventory. A FortiMail with its management interface on 0.0.0.0 and IBE enabled sits in TRIS ACT, the top action band. The same build on an appliance whose management interface is reachable only through an admin VPN, with IBE disabled, scores several bands lower, because neither the vulnerable handler nor the attacker path is reachable. One of our customers has nine FortiMail appliances; two of them are internet-exposed with IBE on, and those two are the only ones that move to the top of the queue.

Blast radius on compromise. A compromised FortiMail is a mail tap, a DKIM key leak, and an LDAP credential leak in one. TRIS raises findings on appliances that sit on data paths other systems trust, because the follow-on radius is wider than the box itself.

Mitigate, hunt, and triage

1. Shut IBE off at the CLI, now. Fortinet's workaround is three lines, and it is the only mitigation available until the fix lands.

config system encryption ibe
  set status disable
end

This closes the vulnerable handler without touching the rest of the mail flow. If you were not using IBE, the change is invisible to users.

2. Pull the management interface off the public internet. If anything that reaches the FortiMail GUI from an untrusted network is business-critical, something has gone wrong upstream. Restrict administrative access to a jump host or an admin VPN, and bind the GUI to the trusted interface only. This defends against the next FortiMail CVE as well as this one.

3. Hunt for the three artifacts. On every FortiMail appliance in scope, check for the presence of /data/bin/webconsole, /bin/smit, and any recent modification of /data/bin/mailservice. Compare file hashes against a known-good appliance of the same build. Treat any match as a confirmed compromise and move to incident response.

4. Rotate what the box held. DKIM private keys, LDAP bind credentials, S/MIME signing certificates, and the IBE master keys were all accessible to the webshell. On a confirmed compromise, rotate all of them and re-sign outbound mail.

5. Watch for the patches. Fortinet named 8.0.2, 7.6.7, and 7.4.9 as the fixed builds. The 7.2 branch is end-of-support territory; appliances on it need to migrate to 7.4 or later rather than wait for a backport that may not come.

Three days is not enough time. The federal KEV deadline was October 4, three days after a disclosure with no patch and a published active-exploitation flag. If you waited for the fix to triage, you spent those three days running the vulnerable version. The right unit of time is "before the next shift change", and the mitigation above gets you there in minutes.

How CVEasy AI surfaces this

FortiMail is one node in your Continuous Threat Exposure Management inventory, not a special case. CVEasy AI, the number one local-first CTEM platform, ingests the real sources on this one: the Fortinet PSIRT feed, the CISA KEV catalog, and the field reports that first described the webshell drop. TRIS runs those signals against the FortiMail inventory already on your side of the network, scores each appliance by its own exposure rather than the CVSS headline, and tells you which two of your nine appliances need the CLI workaround before the next mail delivery cycle. Your mail content, your LDAP binds, and your inventory never leave your hardware, which matters for an appliance whose entire job is to hold the archive of what your organization has written down.

The point of a CTEM program is that the day the next FortiMail zero-day lands, you already know how many you have, where they sit, and which ones have the vulnerable feature turned on. The point of TRIS is that you work the two that matter first.

Sources: Fortinet PSIRT FG-IR-26-175, NVD CVE-2026-104286, CISA KEV catalog, CWE-22, CWE-158, runZero FortiMail exposure, Dark Web Intelligence field reporting

Which of your FortiMail appliances is actually in the fire?

CVEasy AI maps your edge inventory, scores each FortiMail against CVE-2026-104286 by its own exposure, and surfaces the ones that still have IBE on with the GUI reachable from the public internet.

Related reading