Introduction
An unauthenticated SQL injection in the JetEngine WordPress plugin's Custom Content Type REST API allows any external attacker to extract sensitive database contents without needing credentials or user interaction. For the many WordPress sites relying on JetEngine's dynamic content features with publicly exposed CCT endpoints, this vulnerability quietly turns a search parameter into a direct line to the database.
JetEngine, developed by Crocoblock, is a widely used dynamic content plugin for WordPress that integrates with major page builders including Elementor, Gutenberg, Bricks, and Divi. Crocoblock has been building WordPress products since 2018, and JetEngine enables developers to create custom post types, taxonomies, and REST API endpoints for remote data management. Its popularity among WordPress professionals makes this vulnerability relevant across a significant number of production sites.
Technical Information
CVE-2026-4352 carries a CVSS 3.1 base score of 7.5 with the vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N. The scoring reflects a network exploitable flaw with low attack complexity, no required privileges, no user interaction, and high impact to confidentiality. Integrity and availability are not directly affected, but the ability to read arbitrary database contents is a serious data exfiltration risk.
Root Cause
The vulnerability resides in the Custom Content Type (CCT) REST API search endpoint. When a request includes the _cct_search parameter, the plugin interpolates its value directly into a SQL query string using PHP's sprintf() function. Critically, this interpolation occurs without any input sanitization and without using $wpdb->prepare(), which is the standard WordPress method for safely formatting SQL queries with parameterized placeholders.
This alone would be a textbook SQL injection, but an additional WordPress internals nuance makes it reliably exploitable. At bootstrap, WordPress applies wp_magic_quotes() to all superglobals ($_GET, $_POST, $_COOKIE, $_REQUEST), which adds backslash escaping to single quotes and other special characters. Under normal circumstances, this escaping would prevent a naive single quote injection from breaking out of a string context in the SQL query.
However, the WordPress REST API internally calls wp_unslash() on all $_GET parameters before passing them to endpoint callbacks. This strips the backslash escaping that wp_magic_quotes() applied, effectively removing the only layer of protection that stood between the raw user input and the SQL query. The result is that single quote characters pass through to the sprintf() call completely unescaped, allowing an attacker to break out of the intended query structure.
Attack Flow
The exploitation path follows these steps:
-
Prerequisite identification: The attacker identifies a WordPress site running JetEngine with the Custom Content Types module enabled and at least one CCT configured with a public REST GET endpoint. This is the required precondition; without a public CCT REST endpoint, the vulnerable code path is not reachable.
-
Crafting the request: The attacker sends an unauthenticated HTTP GET request to the CCT REST API search endpoint, supplying a malicious value in the
_cct_searchparameter. The payload includes single quotes to break out of the original query's string context, followed by additional SQL clauses (such asUNION SELECTstatements) designed to extract data from other database tables. -
Bypassing wp_magic_quotes: When the request arrives, WordPress's
wp_magic_quotes()escapes the single quotes in the$_GETsuperglobal. However, the REST API framework then callswp_unslash(), which removes those escapes before the parameter value reaches the JetEngine endpoint handler. -
SQL injection execution: The unescaped, attacker controlled value is passed into
sprintf()and interpolated directly into the SQL query string. The injected SQL executes against the WordPress database, and the results are returned through the REST API response. -
Data exfiltration: The attacker can iteratively extract sensitive information from the database, including user credentials, email addresses, configuration data, and any other content stored in the WordPress database.
The CWE classification is CWE-89 (Improper Neutralization of Special Elements used in an SQL Command), which accurately describes the failure to sanitize user input before embedding it in a SQL statement.
Configuration Dependency
It is worth emphasizing that this vulnerability is not exploitable on every JetEngine installation. The Custom Content Types module must be explicitly enabled, and at least one CCT must be configured with a public REST GET endpoint. Sites that do not use the CCT feature, or that have not exposed any CCT endpoints publicly, are not vulnerable to this specific attack vector.
Patch Information
Crocoblock addressed CVE-2026-4352 in JetEngine version 3.8.6.2, which was released prior to the public disclosure on April 13, 2026. Wordfence confirms the remediation: update to version 3.8.6.2 or any newer patched version.
The changelog for version 3.8.6.2 (confirmed from the vendor's release notes) lists two relevant fixes:
- FIX: Query Builder. CCT query type. Possible SQL injection in some cases — this is the direct fix for CVE-2026-4352, addressing the
_cct_searchparameter injection. - FIX: Query Builder. SQL query type. More strict check for input filter props to avoid potential SQL injections — a related hardening fix that tightens input validation on the SQL query type's filter properties.
Because JetEngine is a commercial (closed source) WordPress plugin distributed through Crocoblock's marketplace and not via a public repository, no source level diff is publicly available. However, the nature of the fix is well understood from the advisory context: the patch replaces the unsafe sprintf() string interpolation with proper parameterized queries using $wpdb->prepare(), ensuring that user supplied search values are escaped before being embedded into the SQL statement. This is the standard WordPress pattern for preventing SQL injection; $wpdb->prepare() uses placeholders (%s, %d) that are safely quoted and escaped by the WordPress database abstraction layer.
Site administrators running any version of JetEngine up to and including 3.8.6.1 should update to at least version 3.8.6.2 immediately. At the time of this writing, the latest available release is 3.8.8, which includes additional unrelated improvements.
If immediate patching is not feasible due to change management constraints or compatibility testing requirements, administrators can reduce the attack surface through configuration changes. Because the exploit requires a public REST GET endpoint, administrators should temporarily disable the Custom Content Types module entirely. Alternatively, reconfiguring all Custom Content Types to ensure no public REST GET endpoints are exposed will eliminate the attack path until the patch can be safely deployed.
Affected Systems and Versions
- Plugin: JetEngine (by Crocoblock)
- Affected versions: All versions up to and including 3.8.6.1
- Fixed version: 3.8.6.2
- Platform: WordPress
- Vulnerable configuration: The Custom Content Types module must be enabled, and at least one CCT must be configured with a public REST GET endpoint
Vendor Security History
The JetEngine plugin has a notable history of security issues. Wordfence has documented 18 distinct vulnerabilities for the plugin. A pattern of high severity flaws discovered in early 2026 is particularly concerning:
| CVE | Publication Date | CVSS | Type |
|---|---|---|---|
| CVE-2026-4352 | April 13, 2026 | 7.5 High | Unauthenticated SQL Injection |
| CVE-2026-4662 | March 23, 2026 | 7.5 High | Unauthenticated SQL Injection |
| CVE-2026-28134 | February 26, 2026 | 8.8 High | Authenticated Remote Code Execution |
Three high severity vulnerabilities in under two months, including two separate SQL injection flaws, suggests that organizations using Crocoblock products should implement rigorous security monitoring and maintain aggressive patching schedules. The recurring nature of SQL injection findings in particular may indicate systemic patterns in how user input is handled across the plugin's codebase.



