CVE-2026-57624: Verified Reproduction
CVE-2026-57624: Blocksy Companion Pro unauthenticated remote code execution
CVE-2026-57624 is verified against the affected target. Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00234.
What Is CVE-2026-57624?
CVE-2026-57624 is a critical unauthenticated remote code execution vulnerability (CWE-94) in the Blocksy Companion Pro WordPress plugin, caused by its Code Editor Gutenberg block executing arbitrary PHP with no execution-context check. Pruva reproduced it (reproduction REPRO-2026-00234).
CVE-2026-57624 Severity & CVSS Score
CVE-2026-57624 is rated critical severity, with a CVSS base score of 10.0 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
How to Reproduce CVE-2026-57624
pruva-verify REPRO-2026-00234 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00234/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-57624
- reached the target end-to-end
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
PHP source placed inside a blocksy-companion-pro/code-editor Gutenberg block (block innerHTML); rendered unauthenticated via the standard WP do_blocks() single-view path of a published ct_content_block.
- Unauthenticated HTTP GET (no cookies/credentials) to /ct_content_block/<slug>/
- WP do_blocks()
- blocksy-companion-pro/code-editor render_callback
- get_eval_content()
- eval('?>'.$code)
- shell_exec('id; whoami; hostname; uname -a'). Command output (uid=33(www-data)) returned in HTTP body and written to a marker file by www-data.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-57624
Blocksy Companion Pro (by Creative Themes) ships a premium "Code Editor"
Gutenberg block (blocksy-companion-pro/code-editor) registered in
framework/premium/features/code-editor.php. The block's render_callback
extracts PHP source from the block innerHTML (or the code attribute) and
passes it to get_eval_content(), which executes it with eval('?>' . $code).
In versions <= 2.1.46 the callback performed no execution-context check, so
the block executed arbitrary PHP whenever it was rendered through the standard
WordPress block renderer (do_blocks()) — for example when an unauthenticated
visitor requested the single-view URL of a published ct_content_block whose
post_content contained a code-editor block. This yields unauthenticated
remote code execution (CVSS 10.0, CWE-94). The vendor fix in 2.1.47 adds a
guard that only allows execution when the block is rendered through the
legitimate Blocksy content-block renderer (which sets an explicit
ct_allow_code_editor flag); the standard do_blocks path no longer executes
the code.
- Package / component affected:
blocksy-companion-proplugin,Blocksy\CodeEditorclass inframework/premium/features/code-editor.php(theblocksy-companion-pro/code-editorGutenberg block render callback). - Affected versions: Blocksy Companion Pro <= 2.1.46 (fixed in 2.1.47).
- Risk level: Critical (CVSS 3.1 10.0,
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H). - Consequences: An unauthenticated remote attacker can execute arbitrary PHP
— and therefore arbitrary operating-system commands — in the context of the
web server (
www-data), leading to full site compromise, data exfiltration, and lateral movement on the host.
Impact Parity
- Disclosed / claimed maximum impact: Unauthenticated Remote Code Execution (Patchstack: "Required privilege: Unauthenticated", CVSS 10.0, CWE-94).
- Reproduced impact from this run: Unauthenticated remote code execution
confirmed end-to-end. An HTTP GET with no cookies/credentials to a published
content-block single-view URL caused the code-editor block's
render_callbacktoeval()attacker-controlled PHP that ranshell_exec("id; whoami; hostname; uname -a"). The command output (uid=33(www-data) ..., hostname, kernel string) appeared in the HTTP response and was written to a marker file by thewww-datauser inside the WordPress container. - Parity:
full— the claimed unauthenticated code execution was demonstrated with concrete command output, plus a fixed-version negative control proving the patch blocks it. - Not demonstrated: n/a (code execution was demonstrated, not merely a
crash). The only element not reproduced in isolation is the unauthenticated
injection of the code-editor block content into a content block; that is the
companion IDOR CVE-2026-57630 (a separate, concurrently-disclosed CVE). The
CVE-2026-57624 RCE primitive — unauthenticated
eval()execution of the block content via the standarddo_blockspath — is fully reproduced.
Root Cause
CodeEditor::__construct() registers the block with a render_callback that
calls get_eval_content():
register_block_type('blocksy-companion-pro/code-editor', [
'api_version' => 3,
'render_callback' => function ($attributes, $content, $block) {
// (vulnerable <=2.1.46: NO context guard here)
if (! empty($content)) {
$inline_code = str_replace('<pre class="wp-block-code"><code>', '',
str_replace('</code></pre>', '',
html_entity_decode(htmlspecialchars_decode($content))));
return $this->get_eval_content($inline_code);
}
if (empty($attributes['code'])) return '';
return $this->get_eval_content($attributes['code']);
}
]);
get_eval_content() runs eval('?' . '>' . $inline_code . $ending) — i.e. it
executes the block's innerHTML as PHP. Because there was no check on where the
block was being rendered, the code ran in every rendering context, including the
plain do_blocks() single-post rendering that an unauthenticated visitor
triggers by requesting the content block's URL.
The fix (2.1.47, present in 2.1.48) inserts two guards at the top of the callback:
if (is_admin()) { return ''; }
if (empty($block->parsed_block['ct_allow_code_editor'])) { return ''; }
The ct_allow_code_editor flag is set only by
CustomPostTypeRenderer::mark_code_editor_blocks() (in
framework/premium/features/render-custom-post-type.php), which runs via the
blocksy:block-parser:result filter during the legitimate Blocksy content-block
renderer. The standard WordPress do_blocks() path used for a content block's
own single-view URL does not apply that filter, so ct_allow_code_editor is
absent there and the patched callback returns '' instead of eval()-ing. This
matches the vendor changelog entries "Code editor block - restrict execution to
explicit renderer context" and "Code Editor block - restrict post types for
which it can be executed".
Why the REST block-renderer is NOT the vector
The WordPress core WP_REST_Block_Renderer_Controller::get_item_permissions_check()
has required edit_posts (or edit_post for a supplied post_id) since WP 5.0;
an unauthenticated caller receives HTTP 401 block_cannot_read. This was
verified empirically on the deployed WordPress 7.0. Additionally the code-editor
block registers no attributes schema, so the REST controller rejects a code
attribute (rest_additional_properties_forbidden). The unauthenticated vector is
therefore the do_blocks() single-view path, not the REST block-renderer.
Reproduction Steps
- Script:
bundle/repro/reproduction_steps.sh(self-contained, idempotent). - What it does:
- Bundles the real Blocksy Companion Pro v2.1.48 plugin (GPL-mirror copy,
pre-activated so the
Premium/CodeEditorclasses load without a license) and the free Blocksy theme. - Builds two plugin zips from the same real code:
- vulnerable —
framework/premium/features/code-editor.phpwith the CVE-2026-57624ct_allow_code_editorexecution-context guard removed (restoring the <=2.1.46 render-callback state); - fixed — original 2.1.48 (guard present). A build-sanity grep confirms the guard is present in the fixed zip and absent in the vulnerable zip.
- vulnerable —
- Deploys a Docker stack: MariaDB + two
wordpress:php8.2-apache(WordPress 7.0) instances — one with the vulnerable plugin, one with the fixed plugin — plus the Blocksy theme on each. - Creates a published
ct_content_blockon each instance whosepost_contentis ablocksy-companion-pro/code-editorblock whose PHP payload runsshell_exec("id; whoami; hostname; uname -a")and writes a marker file. (Setup step; in a real attack this block content is injected unauthenticated via the companion IDOR CVE-2026-57630.) - Sends an unauthenticated HTTP GET (no cookies/credentials) to the content block's single-view URL on each instance.
- Verifies the marker file + command output on the vulnerable instance and confirms the fixed instance produces no marker and no code output.
- Writes
bundle/repro/runtime_manifest.json.
- Bundles the real Blocksy Companion Pro v2.1.48 plugin (GPL-mirror copy,
pre-activated so the
- Expected evidence of reproduction:
- Vulnerable: marker file
/tmp/rce_marker.txtwritten bywww-datacontaininguid=33(www-data) ..., plusBLOCKSY_RCE_EXECUTED::uid=33(...)in the HTTP response body. - Fixed:
NO_MARKER_FILE, zeroBLOCKSY_RCE_EXECUTEDoccurrences in the response (thect_allow_code_editorguard returns'').
- Vulnerable: marker file
Evidence
bundle/logs/reproduction_steps.log— full run transcript (both passes).bundle/logs/vuln_marker.txt— command output captured from the vulnerable container:RCE_CONFIRMED CMD_OUTPUT: uid=33(www-data) gid=33(www-data) groups=33(www-data) www-data <container hostname> Linux <hostname> 7.0.14-arch1-1 ... x86_64 GNU/Linuxbundle/logs/fixed_marker_check.txt—NO_MARKER_FILE(fixed build blocks).bundle/logs/code-editor-fix-diff.txt— unified diff of the exact guard reverted (if (empty($block->parsed_block['ct_allow_code_editor'])) { return ''; }removed).bundle/artifacts/http/vuln_response.html— HTTP body containingBLOCKSY_RCE_EXECUTED::uid=33(www-data) gid=33(www-data) groups=33(www-data).bundle/artifacts/http/fixed_response.html— HTTP body with zeroBLOCKSY_RCE_EXECUTEDoccurrences.bundle/artifacts/code-editor.vuln.php/code-editor.fixed.php— the vulnerable and fixedCodeEditorsource as deployed.bundle/repro/runtime_manifest.json— runtime evidence manifest (entrypoint_kind=api_remote,service_started=true,healthcheck_passed=true,target_path_reached=true).
Environment: Docker; mariadb:10.11; wordpress:php8.2-apache
(WordPress 7.0); Blocksy theme 2.1.48; Blocksy Companion Pro 2.1.48 (vulnerable
build = guard reverted; fixed build = original). The unauthenticated requests
were issued from a separate container on the compose network (no WordPress auth
cookies), i.e. a genuine logged-out HTTP client.
Recommendations / Next Steps
- Upgrade: Update Blocksy Companion Pro to 2.1.47 or later (the
ct_allow_code_editorexecution-context guard). The reproduction shows the patched build blocks thedo_blocksexecution path. - Defense in depth: In addition to the context guard, treat the code-editor
block as a high-risk primitive: restrict the
ct_content_blockpost type tomanage_optionsfor create/edit (already the case), and consider disabling the code-editor block entirely on sites that do not need server-side PHP execution. - WAF / mitigation: Block unauthenticated requests to
/ct_content_block/<slug>/and toadmin-ajax.phpactionsblc_retrieve_popup_content/blc_retrieve_mega_menu_contentwhen the content block contains a code-editor block, until all sites are patched. - Companion IDOR: Also remediate CVE-2026-57630 (unauthenticated IDOR) which is the realistic unauthenticated injection path for the code-editor block content; the two CVEs combine into a single-request unauthenticated RCE on a vulnerable+unpatched-IDOR site.
- Testing: Add an automated test that renders a code-editor block via the
standard
do_blocks()path (not theContentBlocksRenderer) and asserts the output is empty on patched builds.
Additional Notes
- Idempotency: The script tears down its compose stack (
down -v) at start and rebuilds from the bundled artifacts, so it can be run repeatedly. It was executed twice consecutively; both runs ended withexit 0and the same vulnerable/fixed differential. - Vulnerable-source caveat: The vulnerable <=2.1.46 plugin build is not
downloadable (the commercial Pro plugin is distributed only via freemius and
GPL mirrors keep only the latest release). The reproduction therefore builds
the vulnerable variant from the real 2.1.48 plugin by reverting the exact
CVE-2026-57624 security guard (
ct_allow_code_editorcontext check), which restores the pre-2.1.47 render-callback state. Theeval()mechanism, block registration, attribute/innerHTML handling andget_eval_content()are all the unmodified vendor code; only the 2.1.47 guard is removed. The fixed variant (original 2.1.48) serves as the negative control. - Licensing: The GPL-mirror 2.1.48 copy is pre-activated
(
Capabilities::get_plan()returnsagency_v2without a license), so thePremium/CodeEditorblock registers and theblocksy-companion-pro/code-editorblock is available without a valid freemius key — matching a real licensed deployment where an admin has activated Pro. - Scope: The demonstrated surface is the unauthenticated
do_blocksHTTP path (api_remote), matching the ticket'sclaimed_surface=api_remote. The attacker-controlled code injection itself is CVE-2026-57630 (separate), noted for completeness; the CVE-2026-57624 RCE primitive (unauthenticatedevalexecution) is fully reproduced and differentially validated against the patch.
CVE-2026-57624 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-57624
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-57624
FAQ: CVE-2026-57624
How does the CVE-2026-57624 unauthenticated RCE work?
do_blocks()) — for example when an unauthenticated visitor simply requests the single-view URL of a published ct_content_block whose post_content contains a code-editor block, triggering server-side PHP execution with no authentication required.Which Blocksy Companion Pro versions are affected by CVE-2026-57624, and where is it fixed?
ct_allow_code_editor flag), so the standard do_blocks() path no longer executes it.How severe is CVE-2026-57624?
How can I reproduce CVE-2026-57624?
References for CVE-2026-57624
Authoritative sources for CVE-2026-57624 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.