2026-10-04 · CVE-2026-104286
CVE-2026-104286: A NULL Byte, a Path Traversal, and No Patch Yet
On October 1, 2026, Fortinet disclosed CVE-2026-104286, a CVSS 9.8 vulnerability in FortiMail's webmail interface that lets an unauthenticated attacker write arbitrary files to the underlying operating system. CISA added it to the Known Exploited Vulnerabilities catalog the same day, with a remediation deadline of October 4 — today, as we're writing this — for federal civilian agencies. At the time of disclosure, Fortinet had patches for some branches but not all of them, which means a meaningful chunk of the affected install base is currently running on mitigations instead of a fix.
That's the detail that makes this one worth a closer look: it's not just another unauthenticated-RCE-adjacent bug in a perimeter appliance, it's one where "patch it" isn't universally an option yet.
What the vulnerability actually is
CVE-2026-104286 is a combination of two classic, well-understood bug classes stacked together: a path traversal flaw and improper neutralization of NULL byte characters, both reachable through FortiMail's Identity-Based Encryption (IBE) webmail path. An attacker sends a crafted HTTP or HTTPS request containing traversal sequences (../../../) and a NULL byte to the IBE endpoint, and the underlying file-write logic doesn't sufficiently validate either the resulting path or where the string effectively terminates.
The NULL byte detail matters mechanically. Older C-style string handling (and plenty of code that calls into it) treats \x00 as end-of-string, so a request like report.pdf\x00../../../etc/cron.d/x can pass a .pdf extension check while the actual filesystem write targets something else entirely. It's an old trick — NULL byte injection bugs go back to early-2000s PHP — but it keeps resurfacing anywhere an extension or type check happens on a string before a lower-level file API consumes the same string without re-validating it.
Put the two together and you get an unauthenticated, network-reachable arbitrary file write: no credentials, no user interaction, just a crafted request to a service most FortiMail deployments expose for legitimate business reasons.
From file write to real compromise
Arbitrary file write on its own isn't remote code execution — it's a primitive. What an attacker does with it depends entirely on what the compromised system will read, execute, or trust afterward. On a mail security gateway, researchers have pointed to several realistic escalation paths once write access is established:
- Drop a web shell into a path the webmail service serves, if one is reachable.
- Overwrite a scheduled job or startup script the appliance already trusts and executes as a privileged user.
- Tamper with mail-scanning configuration to wave through specific senders or attachment types.
- Plant a persistence mechanism that survives a reboot, then use the compromised gateway as a pivot point into the internal network it was supposed to be protecting.
That's the pattern worth internalizing, not the specific CVE number: a file-write primitive is only as dangerous as the blast radius of whatever reads the file back. On a mail gateway specifically, the blast radius is unusually bad, because the system sits at a trust boundary — it's allowed to talk to the internet, and it's allowed to talk to internal mail infrastructure, which is exactly the kind of dual trust that makes a compromised appliance valuable as a foothold rather than just a nuisance.
What's patched, and what isn't
| FortiMail branch | Status as of disclosure |
|---|---|
| 8.0 | Fix available |
| 7.6 | Fix available |
| 7.4 | Fix pending |
| 7.2 | Fix pending |
For branches without a shipped fix, Fortinet's guidance is mitigation, not resolution: disable the IBE webmail feature if it isn't in active use, restrict network access to the webmail interface to trusted sources only, and review logs for indicators of compromise against the known exploitation pattern. None of those are substitutes for a patch — they're damage control until one exists.
"Patch Tuesday" thinking doesn't apply cleanly here, and it's worth calling out explicitly: when a vendor discloses a vulnerability under active exploitation before every affected branch has a fix, the right response isn't to queue the usual change-management ticket and wait for the maintenance window. It's to apply the vendor's interim mitigation immediately, treat the eventual patch as a second, separate action item, and verify both — because an organization that stops at "we applied the workaround" and never circles back once the real fix ships is functionally still unpatched.
Why this keeps happening to mail gateways specifically
Mail security appliances are a recurring target for this exact failure mode for a structural reason: they're designed to accept untrusted, often attacker-controlled input — that's the whole point of a mail gateway — while also exposing an administrative and webmail surface that was historically assumed to be lower-risk than the mail-processing pipeline itself. That assumption is backwards. The webmail/admin interface is frequently the least-scrutinized code path on the box, because the organization's threat model is built around "malicious email," not "malicious HTTP request to the management plane." Attackers have noticed the same gap repeatedly across FortiMail, FortiOS, and comparable gateway products over the past several years, and this CVE is simply the latest instance of that pattern, not an outlier.
What this means for how we teach it
Path traversal plus a NULL byte trick is a genuinely good exercise for exactly the reason it's a genuinely good exploit: it's two individually well-known bug classes that most training material teaches in isolation, and the real skill is recognizing that a type check and a path-sanitization check can each pass independently while the combined behavior still fails. That's a harder thing to internalize from a slide than from a lab where you watch a .pdf-suffixed, traversal-laden filename sail past an extension check and land exactly where you pointed it.
It's also a useful case study in something our own curriculum keeps coming back to: the gap between finding a primitive and weaponizing it. Plenty of students can spot ../../../ in a request. Fewer have practiced the second half — reasoning through what a target system will actually read, execute, or trust once you can write to it, and picking the one file that turns "I can write somewhere" into "I have a shell." That's the chain-building instinct a CVE writeup can describe but can't teach on its own.
The takeaway
CVE-2026-104286 isn't notable because path traversal or NULL byte injection are new — both are decades-old bug classes that keep resurfacing because the fix (consistent, defense-in-depth input validation across every layer that touches a filename) is simple to state and surprisingly easy to get subtly wrong in practice. It's notable because it landed on a security appliance, under active exploitation, with patches still rolling out branch by branch — which means for a real slice of the install base, the right move today is the mitigation, not a patch that doesn't exist yet for their version. If you're responsible for a FortiMail deployment on 7.2 or 7.4, that's the action item before anything else in this post.