FortiWeb `cgi-bin/fwbcgi` Path Traversal Authentication Bypass Leading to Rogue Admin Creation (CVE-2025-64446)
by litndat · 2026-07-06
- Severity
- Critical
- CVE
- CVE-2025-64446
- Category
- network
- Affected product
- Fortinet FortiWeb (Web Application Firewall appliance)
- Affected versions
- 8.0.0 – 8.0.1, 7.6.0 – 7.6.4, 7.4.0 – 7.4.9, 7.2.0 – 7.2.11, 7.0.0 – 7.0.11 (per source repository)
- Disclosed
- 2026-07-06
- Patch status
- unpatched
Tags
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-06 |
| Last Updated | 2026-07-06 |
| Author / Researcher | litndat |
| CVE / Advisory | CVE-2025-64446 |
| Category | network |
| Severity | Critical |
| CVSS Score | 9.8 (per NVD) |
| Status | PoC |
| Tags | fortiweb, fortinet, waf, authentication-bypass, path-traversal, cgiinfo, cwe-22, cwe-288, admin-account-creation, python |
| Related | CVE-2025-58034 (post-auth OS command injection via SAML user CLI, chained after this bypass) |
Affected Target
| Field | Value |
|---|---|
| Software / System | Fortinet FortiWeb (Web Application Firewall appliance) |
| Versions Affected | 8.0.0 – 8.0.1, 7.6.0 – 7.6.4, 7.4.0 – 7.4.9, 7.2.0 – 7.2.11, 7.0.0 – 7.0.11 (per source repository) |
| Language / Platform | Python 3 exploit client targeting FortiWeb’s HTTPS management/API interface |
| Authentication Required | No — this is the authentication-bypass step itself |
| Network Access Required | Yes (HTTPS access to the FortiWeb admin/API port, typically 443) |
Summary
FortiWeb exposes an internal CGI handler (cgi-bin/fwbcgi) that is reachable through the authenticated cmdb REST API path by appending a relative path-traversal sequence (../) after a request to a nonexistent object (admin%3f). Because path handling for the internal CGI target happens outside the access-control check tied to the /api/v2.0/cmdb/... prefix, the traversal routes the request to the internal CGI handler while bypassing the authentication gate that would normally apply to it. The handler additionally trusts a CGIINFO HTTP header — a base64-encoded JSON blob asserting an authenticated admin identity — without independently verifying a valid session. The PoC combines both bugs to submit an unauthenticated “add local user” request that creates a brand-new, fully privileged local administrator account with no source-IP restriction (trusthostv4/trusthostv6 = 0.0.0.0/0 / ::/0). Once this rogue admin account exists, an attacker can log in normally and, per the repository’s documentation, chain into CVE-2025-58034 (an authenticated OS command injection in the SAML user CLI configuration flow) for full device compromise.
Vulnerability Details
Root Cause
The exploit targets the following endpoint, which appends a traversal sequence after a bogus object name to escape the cmdb API’s authentication scope and land on the internal fwbcgi CGI binary:
POST /api/v2.0/cmdb/system/admin%3f/../../../../../cgi-bin/fwbcgi
The request also carries a CGIINFO header — base64-encoded JSON that the backend appears to trust as an already-authenticated session context instead of re-deriving identity from a validated session/cookie:
| |
The JSON body sent alongside it is a standard FortiWeb cmdb “add local admin user” payload (q_type: 1) with access-profile: prof_admin (super-admin equivalent) and no trusted-host restriction, so a successful response (HTTP 200) means a new, fully privileged admin account was silently created without ever authenticating.
Attack Vector
- Attacker sends an unauthenticated
POSTto/api/v2.0/cmdb/system/admin%3f/../../../../../cgi-bin/fwbcgion the target FortiWeb’s management/API interface. - The trailing
../../../../../traversal collapses the path down tocgi-bin/fwbcgi, which is processed outside the access-control logic bound to thecmdbAPI prefix. - The
CGIINFOheader (base64 JSON assertingusername=admin,profname=prof_admin,vdom=root) is accepted by the CGI handler as a trusted session/authorization context. - The POST body instructs the backend to add a new local user with attacker-chosen username/password,
access-profile=prof_admin, andtrusthostv4=0.0.0.0/0/trusthostv6=::/0(unrestricted source access). - A
200response confirms the rogue admin account now exists; the attacker logs in through the normal GUI/CLI using the newly created credentials. - (Documented chain) Once authenticated, the attacker can exploit CVE-2025-58034 by editing a SAML user’s entity name with a shell metacharacter payload (e.g.
edit "id") insideconfig user saml-user, causing FortiWeb to break out of the configuration parser and execute the injected OS command.
Impact
- Complete unauthenticated bypass of FortiWeb’s administrative authentication.
- Creation of a fully privileged, network-reachable (unrestricted trusted-host) admin account.
- Chainable into authenticated OS command injection (CVE-2025-58034) for full appliance compromise, and by extension compromise of the trust placed in the WAF protecting downstream web applications.
Environment / Lab Setup
Target: FortiWeb appliance, firmware in the vulnerable range listed above,
management/API HTTPS interface reachable on port 443.
Attacker: Python 3
Standard library only (http.client, ssl, base64, json, argparse, uuid)
NOTE: the script as committed does `import slogsec` and calls
`slogsec.get_logger("api")` for output logging. `slogsec` is not a
published/available Python package — replace those two lines with
Python's standard `logging` module (or simple print statements)
before running. This is the only change needed; the request/exploit
logic itself is unmodified from the source repository.
Proof of Concept
PoC Script
See
exploit.pyin this folder.
| |
On success the script prints the newly created admin username/password, which can then be used to log into the FortiWeb GUI/CLI as a super-admin.
Detection & Indicators of Compromise
- HTTP POST requests to URIs matching:
/api/v2.0/cmdb/system/*%3f/../*cgi-bin/fwbcgi
(path-traversal sequences preceding cgi-bin/fwbcgi)
- Presence of a "CGIINFO" request header carrying base64-encoded JSON on
otherwise unauthenticated requests
- New entries in `config system admin` with:
- trusthostv4 0.0.0.0/0 and/or trusthostv6 ::/0
- unexplained creation time with no corresponding legitimate admin login
- short/random usernames (e.g. 8-character UUID fragments)
- Subsequent CLI activity under `config user saml-user` containing shell
metacharacters (backticks, $()) in the `edit` object name — indicator of
the CVE-2025-58034 follow-on command injection
Signs of compromise:
- Unrecognized local admin accounts with unrestricted trusted hosts.
- FortiWeb admin login events from unfamiliar source IPs shortly after a new account’s creation timestamp.
- Unexpected outbound connections or process execution originating from the FortiWeb appliance itself.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade FortiWeb to a version outside the affected ranges (per Fortinet PSIRT advisories for CVE-2025-64446 and CVE-2025-58034). |
| Interim mitigation | Do not expose the FortiWeb management/API interface to the Internet; restrict access via trusted-host/ACLs; audit config system admin for unexpected accounts and unrestricted trusthostv4/trusthostv6 entries; monitor for path-traversal sequences targeting cgi-bin/fwbcgi in access logs. |
References
Notes
Mirrored from https://github.com/litndat/Vulnerability-CVE-2025-64446-CVE-2025-58034 on 2026-07-06. The repository’s original README is written in Vietnamese and documents both CVE-2025-64446 (this entry) and the chained CVE-2025-58034 authenticated OS command injection. The included exploit.py imports a non-existent slogsec module (import slogsec, log = slogsec.get_logger("api")) — this is not a published PyPI package, so the script fails at import time until those lines are swapped for standard logging/print calls. Aside from that import issue, the HTTP request construction, CGIINFO header, and API payload match the documented real-world FortiWeb auth-bypass technique.
| |