Skip to content

CVE-2026-21643: Fortinet FortiClient EMS SQL Injection

CVE-2026-21643 represents a critical failure in input validation within the Fortinet FortiClient EMS 7.4.4 management console. The vulnerability is characterized as an unauthenticated SQL injection (SQLi) where the application fails to neutralize special characters within the Site HTTP header. Given the administrative nature of the EMS server, this flaw allows a remote attacker to bypass authentication, exfiltrate sensitive configuration data, and potentially achieve Remote Code Execution (RCE) by leveraging PostgreSQL functions.

The inclusion of this CVE in the CISA Known Exploited Vulnerabilities (KEV) catalog emphasizes the immediacy of the threat, as active exploitation campaigns have been observed targeting enterprise environments.

The core of the vulnerability lies in the handling of the Site header during requests to the /api/v1/init_consts endpoint. In a legitimate scenario, this header is used to identify the tenant or site context for the request. However, the backend fails to parameterize this input before incorporating it into a SQL query.

When a request hits /api/v1/init_consts, the application extracts the value of the Site header. This value is then concatenated directly into a query string. An attacker can break the intended SQL syntax by inserting a semicolon (;) or using comment markers (--), allowing them to append entirely new SQL commands to the original statement.

The vulnerability follows a classic “Tainted Input” pattern:

  1. Source: HTTP Header [Site] $\rightarrow$ User-controlled input.
  2. Sink: PostgreSQL Query Execution $\rightarrow$ Direct concatenation.
  3. Impact: Ability to modify the query logic, access the pg_catalog, or interact with the underlying filesystem via COPY or lo_import/lo_export if the database user has sufficient privileges.

The exploitation process is straightforward and requires no authentication.

Attackers typically begin by verifying the vulnerability using error-based or time-based blind SQLi. A common test payload involves attempting to leak the database version: Site: tenant1; SELECT version()--

If the server responds with a PostgreSQL version string or a specific database error, the vulnerability is confirmed.

Once confirmed, the attacker can query the system catalogs to map out the database structure:

  • Extracting user hashes: Site: tenant1; SELECT usename, passwd FROM pg_shadow--
  • Dumping configuration tables: Site: tenant1; SELECT * FROM config_table--

Depending on the database configuration and permissions, RCE is achievable. In PostgreSQL environments, if the database service account has high privileges, attackers can use utilities like pg_read_file or pg_write_file to manipulate the OS. In some cases, specific PostgreSQL extensions or functions can be leveraged to execute shell commands directly.

Detecting this exploitation requires a focused analysis of web server logs and database audit trails.

The primary indicator of compromise (IOC) is the presence of abnormal characters in the Site header of GET requests.

  • Target URL: /api/v1/init_consts
  • Suspicious Patterns:
    • Presence of ;, --, /*, or ' in the Site header.
    • SQL keywords: SELECT, UNION, INSERT, UPDATE, DROP, SLEEP, pg_sleep.

PostgreSQL logs may reveal:

  • Unexpected queries targeting pg_shadow or pg_catalog.
  • A surge in ERROR: syntax error at or near... messages accompanying the requests to /api/v1/init_consts.
  • Unexplained uses of COPY commands targeting the local filesystem.

The following detection strategies should be implemented immediately.

title: FortiClient EMS SQLi via Site Header
logsource:
category: webserver
detection:
selection:
url: '/api/v1/init_costns'
http_header_site:
- '*SELECT*'
- '*UNION*'
- '*--;*'
- '*pg_sleep*'
condition: selection

index=web_logs path="/api/v1/init_consts" | search site_header="*SELECT*" OR site_header="*UNION*" OR site_header="*--;*" OR site_header="*pg_sleep*"

  1. Patching: Update FortiClient EMS to the latest patched version provided by Fortinet.
  2. WAF Hardening: Implement a Web Application Firewall (WAF) rule to block any request to /api/v1/init_consts where the Site header contains SQL keywords or special characters.
  • Input Validation: Transition from string concatenation to strictly parameterized queries (Prepared Statements).
  • Least Privilege: Ensure the database service account running the EMS backend has the minimum required permissions, preventing the use of high-risk functions like pg_read_file.