This is a deadbolt flaw on the front gate, not a bug buried in the basement
CVE-2024-21762 is an out-of-bounds write in Fortinet sslvpnd, the SSL-VPN component used by FortiOS and FortiProxy. A remote attacker can send a specially crafted HTTP request using chunked transfer encoding and corrupt memory before authentication. Affected FortiOS trains are 7.4.0–7.4.2, 7.2.0–7.2.6, 7.0.0–7.0.13, 6.4.0–6.4.14, 6.2.0–6.2.15, and 6.0.0–6.0.17; affected FortiProxy trains are 7.4.0–7.4.2, 7.2.0–7.2.8, 7.0.0–7.0.14, and 2.0.0–2.0.13, with older 1.x branches requiring migration.
Vendor severity matches reality here. The only real friction is that the vulnerable SSL-VPN service must be reachable, but for the population that matters it is *supposed* to be internet-facing, exploitation was important enough for immediate KEV listing, public research showed reliable crash and code-exec paths, and internet scan data showed a very large exposed population.
4 steps from start to impact.
Reach the SSL-VPN listener
443/tcp. Tooling is trivial: a raw socket, openssl s_client, or custom Python HTTP client is enough because no authentication or session setup is required.- SSL-VPN service is enabled
- The interface is reachable from the attacker
- Target runs an affected firmware train
- If SSL-VPN is disabled or isolated behind strict source-IP controls, the attack dies immediately
- Some FortiGate deployments expose management or VPN only to partners, not the whole internet
Trigger sslvpnd chunk parsing
/remote/ so sslvpnd parses an oversized or malformed chunk-length/trailer sequence. Assetnote showed the vulnerable code path lives in HTTP chunked request handling and that patched builds added length checks around this parsing logic.- HTTP request reaches
sslvpndunmodified - Chunked transfer encoding is accepted through the path
- Intermediaries that normalize or reject malformed chunked requests can break the exploit path
- Some reverse-proxy designs are uncommon for FortiGate SSL-VPN and reduce exposure
HTTP.Chunk.Length.Invalid.; network telemetry may show malformed chunked POSTs to /remote/.Corrupt memory and seize execution
sslvpnd. Assetnote documented controlled corruption and a path to code execution, while public scanners showed a safe behavioral test that distinguishes vulnerable from patched devices without full exploitation.- Target must be on a vulnerable build
- Attacker must shape request bytes closely enough to survive parser behavior
- Reliable RCE is harder than a crash, especially across firmware branches
- Exploit reliability can vary by build and appliance model
sslvpnd instability or abrupt TLS session drops; safe verification behavior is covered by Bishop Fox.Use the firewall as a beachhead
- Successful code execution on the appliance
- Appliance has meaningful trust or visibility into internal networks
- Segmentation can limit pivoting from the appliance
- Operational logging on hardened appliances may shorten attacker dwell time
sslvpnd.The supporting signals.
| In-the-wild status | Confirmed exploited. NVD flags this CVE as present in CISA KEV, and CISA added it on 2024-02-09 with a federal due date of 2024-02-16. |
|---|---|
| Proof-of-concept availability | Publicly weaponized enough to matter. Assetnote published deep exploit research, and Bishop Fox released a safe scanner based on observable parser behavior. |
| EPSS | 0.92702 from the provided intel, which is effectively top-tier exploit likelihood; public vulnerability databases place it at roughly 99.8th percentile. |
| KEV status | YES. Added to KEV on 2024-02-09; NVD shows the CISA due date as 2024-02-16. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — pure network attack, no auth, no user click, full CIA impact. |
| Affected surface | Not all FortiGates, but the exposed ones are the dangerous ones. The vulnerable code is in sslvpnd, so the attack population is concentrated in deployments with SSL-VPN enabled and reachable. |
| Fixed versions | FortiOS: 7.4.3+, 7.2.7+, 7.0.14+, 6.4.15+, 6.2.16+, 6.0.18+. FortiProxy: 7.4.3+, 7.2.9+, 7.0.15+, 2.0.14+; older 1.x branches require migration. |
| Exposure and scanning | Shadowserver added active scanning/reporting for this CVE on 2024-02-13, and its March 2024 reporting cited nearly 150,000 vulnerable internet-exposed devices, with 24,000+ in the U.S. |
| Disclosure and discovery | Fortinet PSIRT published on 2024-02-08; the advisory lists discovery as Internal. |
| Vendor workaround nuance | Disable SSL-VPN is the vendor workaround. Fortinet explicitly says disabling webmode is not a valid workaround; a virtual patch signature named HTTP.Chunk.Length.Invalid. is available in FMWP DB update 24.020. |
noisgate verdict.
The decisive factor is that this is pre-auth code execution on an edge VPN service that is intentionally internet-facing. KEV status and public exploit research remove any argument that this is a theoretical lab bug; the reachable population is large enough and the post-compromise position is strong enough to keep it in the top bucket.
Why this verdict
- No attacker foothold required: unauthenticated remote exploitation over HTTPS means there is no prior compromise stage to discount.
- Exposure model amplifies risk: SSL-VPN is commonly internet-facing by design, so the required attacker position is the public internet, not an internal segment or valid account.
- Threat intel supports the vendor number: KEV listing, rapid researcher weaponization, and large internet-exposed counts keep the practical risk aligned with the near-max CVSS.
Why not higher?
There is not much room above this. The only reason this is not a hypothetical 10.0 is that the vulnerable component is not universally enabled across every FortiGate or FortiProxy deployment, so population reach is somewhat narrower than a flaw in the base management plane with no feature dependency.
Why not lower?
Downgrading this because 'not every firewall exposes SSL-VPN' misses the point: the vulnerable population is exactly the population that tends to be exposed to the internet. This is also not an authenticated or post-initial-access bug, so the normal downward pressure from attacker-position friction simply is not there.
What to do — in priority order.
- Disable SSL-VPN if you can — If business permits, turn off the exposed
sslvpndsurface immediately; for this KEV-listed bug, deploy this within hours rather than waiting for the standard noisgate timeline. - Restrict source IPs to the VPN edge — If you cannot disable SSL-VPN, reduce reachable population with aggressive allowlisting, partner-only exposure, or upstream ACLs. For a live KEV issue, get this in place within hours as the minimum containment move.
- Enable Fortinet's virtual patch signature — Use the vendor-provided virtual patch
HTTP.Chunk.Length.Invalid.from FMWP DB update24.020to block malformed chunked requests targeting this parser path. Treat this as an emergency control and deploy within hours. - Hunt for appliance compromise — Review FortiGate/FortiProxy logs, admin changes, config access, and unexpected egress because exploitation evidence exists already. Start this triage within 3 days, and sooner for internet-facing gateways with heavy remote-access use.
Disable webmodedoes not fix this; Fortinet explicitly says it is not a valid workaround.- Endpoint EDR on user laptops does nothing for a memory corruption bug in the firewall appliance itself.
- A generic web WAF is often irrelevant because many FortiGate SSL-VPN deployments are directly exposed and terminate traffic on the appliance.
Crowdsourced verification payload.
Run this from an auditor workstation that can reach the FortiGate/FortiProxy HTTPS listener; do not run it on the appliance. Invoke it as python3 verify_cve_2024_21762.py https://vpn.example.com:443 with no special privileges required. It performs a safe behavioral check similar to the Bishop Fox technique: patched devices respond quickly, while vulnerable devices tend to hang waiting for more chunk data.
#!/usr/bin/env python3
"""
Safe behavioral verifier for CVE-2024-21762.
Usage: python3 verify_cve_2024_21762.py https://host:443
Exit codes:
0 = PATCHED
1 = VULNERABLE
2 = UNKNOWN
"""
import socket
import ssl
import sys
from urllib.parse import urlparse
TIMEOUT = 5.0
def parse_target(arg: str):
if '://' not in arg:
arg = 'https://' + arg
u = urlparse(arg)
if u.scheme != 'https' or not u.hostname:
raise ValueError('Target must be an https URL or host[:port]')
host = u.hostname
port = u.port or 443
return host, port
def main():
if len(sys.argv) != 2:
print('UNKNOWN')
sys.exit(2)
try:
host, port = parse_target(sys.argv[1])
except Exception:
print('UNKNOWN')
sys.exit(2)
payload = (
f"POST /remote/ HTTP/1.1\r\n"
f"Host: {host}\r\n"
f"User-Agent: noisgate-cve-2024-21762-check/1.0\r\n"
f"Transfer-Encoding: chunked\r\n"
f"Connection: close\r\n"
f"\r\n"
f"0000000000000000FF\r\n"
f"\r\n"
f"abcd"
).encode()
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
try:
with socket.create_connection((host, port), timeout=TIMEOUT) as sock:
with ctx.wrap_socket(sock, server_hostname=host) as tls:
tls.settimeout(TIMEOUT)
tls.sendall(payload)
try:
data = tls.recv(1024)
except socket.timeout:
# Vulnerable behavior: connection hangs waiting for more chunk data.
print('VULNERABLE')
sys.exit(1)
if data:
# Patched behavior: parser rejects early and returns a response.
print('PATCHED')
sys.exit(0)
else:
print('UNKNOWN')
sys.exit(2)
except (ssl.SSLError, socket.error, OSError):
print('UNKNOWN')
sys.exit(2)
if __name__ == '__main__':
main()
If you remember one thing.
<= 90 days for any genuinely unreachable stragglers that you have positively proven are not externally exposed.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.