CVE-2026-63030: Verified Reproduction
CVE-2026-63030: WordPress 7.0.1 pre-auth fresh-administrator chain to RCE
CVE-2026-63030 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-00294.
What Is CVE-2026-63030?
CVE-2026-63030 is a critical pre-authentication remote code execution chain in WordPress 7.0.1. An unauthenticated attacker composes several stock REST and post-processing behaviors to create a brand-new administrator account and then execute code, without any prior access. Pruva reproduced the full chain end-to-end (reproduction REPRO-2026-00294).
CVE-2026-63030 Severity & CVSS Score
CVE-2026-63030 is rated critical severity, with a CVSS base score of 9.8 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
How to Reproduce CVE-2026-63030
pruva-verify REPRO-2026-00294 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00294/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-63030
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
Unauthenticated nested JSON requests to stock POST /wp-json/batch/v1 plus attacker-chosen fresh administrator username/password; no owner credential is supplied to the exploit driver.
- REST batch request/handler desynchronization
- shifted posts handler
- scalar author_exclude SQL injection/full-row projection
- oEmbed cache poisoning and partial-update merge
- forged due Customizer changeset
- privileged parse_request REST re-entry
- normal users create handler
- fresh administrator
- wp-login.php
- core plugin uploader
- plugin HTTP command endpoint.
PRUVA-RCE-BEGIN
PRUVA-CMD-MARKER
uid=33(www-data) gid=33(www-data) groups=33(www-data)
PRUVA-RCE-EXIT:0 reproduction_steps.sh How the agent worked
Root Cause and Exploit Chain for CVE-2026-63030
WordPress 7.0.1 contains a composable pre-authentication chain in its stock REST and post-processing paths. A malformed REST batch entry desynchronizes parsed requests from matched handlers; a shifted posts handler then accepts an attacker-controlled scalar author_exclude value that reaches WP_Query::author__not_in without integer normalization. The resulting full-row SQL projection lets an unauthenticated attacker poison post-cache objects. Core oEmbed partial-update and hierarchy-repair behavior turns those transient objects into persistent forged posts, including a due Customizer changeset. While core applies that changeset under its recorded owner context, a forged request post with status parse invokes the stock parse_request hook and re-enters REST dispatch. A nested malformed batch consequently reaches the normal user-creation controller as the owner and creates a fresh attacker-chosen administrator. That new account can authenticate normally, use the core plugin uploader, and execute a command as the web server. WordPress 7.0.2 aligns batch arrays, integer-normalizes the ID list, and blocks nested top-level REST dispatch.
- Affected component: WordPress Core REST batch dispatch,
WP_Query, post/oEmbed cache update behavior, Customizer changeset publication, and nested REST dispatch. - Affected version exercised: stock WordPress 7.0.1, official
wordpress:7.0.1-php8.2-apacheimage pinned tosha256:bfc320ed4f02dd3939186b8020de64203a48a939d6dedcf44cb92cf2368923f5. - Fixed control exercised: WordPress 7.0.2 source at commit
855551c4477bd5a0407221c57dae123c4163b434, over the same pinned base image. - Database: MySQL 8.0 pinned to
sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b, with@@local_infile=0, application-scoped grants, and no globalFILEprivilege. - Risk: Critical. An unauthenticated network attacker can create a new administrator without knowing, recovering, or reusing the sole owner's random password, then obtain arbitrary command execution as Apache's
www-dataidentity.
Impact Parity
- Disclosed/claimed maximum impact: Unauthenticated remote code execution through creation of a fresh attacker-chosen administrator.
- Reproduced impact from this run: Full unauthenticated fresh-administrator creation followed by normal login, core plugin upload, and target-originated command execution as
uid=33(www-data) gid=33(www-data) groups=33(www-data). The final generated script passed twice consecutively; each execution itself recreated and passed two clean vulnerable/fixed matrices. - Parity:
full. - Not demonstrated: None of the claimed chain remains unproved.
Root Cause
Three missing invariants in WordPress 7.0.1 compose into the privilege transition:
- REST batch request/handler array desynchronization.
WP_REST_Server::serve_batch_request_v1()appends a parse error to its request array but, in the vulnerable source, does not append a corresponding entry to the matched-handler array before continuing. Subsequent requests are paired with the next route's handler and permission callback. - Scalar
author__not_inSQL injection. A shifted posts-list handler retains attacker-controlled query parameters. In 7.0.1,author__not_inis normalized only when already represented as an array; a scalar can reach the interpolatedNOT IN (...)SQL clause. A high page size andorderby=nonedisable the ID-only split-query boundary, allowing a complete 23-column forgedwp_posts.*row. - Nested top-level REST dispatch. Core's dynamic
{$new_status}_{$post_type}transition permits the forgedparse_requestpair to callrest_api_loaded()while an outer REST dispatch is active. The vulnerable implementation re-entersserve_request()during the Customizer's temporary owner context. The nested malformed batch then invokesWP_REST_Users_Controller::create_item()with permission checks evaluated as user 1.
The middle state transition uses stock behavior rather than a plugin gadget: an ID-zero embed triggers WP_Embed::shortcode(), which performs a partial wp_update_post() on a real cache row. wp_update_post() first loads and merges all fields from the poisoned cached object; hierarchy repair performs another partial update and persists the forged fields. A due customize_changeset then applies stock custom CSS under the recorded owner context, and the forged status/type transition selects the existing parse_request action.
The fixed release adds batch-array alignment (c8bdf1fa12355f79db94054d307d0e3898b501c9), parses author exclusion values through an integer-only ID list, and guards against nested REST dispatch. The fixed source identity used by the control is commit 855551c4477bd5a0407221c57dae123c4163b434 (WordPress 7.0.2).
Reproduction Steps
- Run
bundle/repro/reproduction_steps.shfrom any working directory (or setPRUVA_ROOTto the bundle directory). - The script verifies the ticket-pinned image digests and exact 7.0.2 source archive, starts isolated MySQL and WordPress targets, and installs each with exactly one owner whose random password is generated inside the installer and is neither printed nor supplied to the exploit driver.
- It confirms no exploit plugin or mu-plugin is present, application DB grants are scoped to
wordpress.*, and@@local_infile=0. - A distinct Python driver container sends unauthenticated HTTP requests through
/wp-json/batch/v1, seeds and rediscovers disposable oEmbed rows through the vulnerable application path, composes the forged changeset/request state, and creates a randomized administrator. - The driver authenticates through
wp-login.php, uploads a randomized proof plugin through the core uploader, and requests it over HTTP to executeprintf 'PRUVA-CMD-MARKER\n'; id. - The exact same trigger is run against WordPress 7.0.2 and must fail before its first disposable oEmbed cache row can be discovered. The script verifies one user and zero
oembed_cacherows afterward. - The script destroys both target stacks, recreates clean databases and targets, and repeats the complete vulnerable/fixed matrix.
Expected success output ends with:
[+] CONFIRMED: WordPress 7.0.1 pre-auth fresh-administrator chain to command execution
[+] Two clean vulnerable/fixed matrices passed
Evidence
The current script records fresh evidence under bundle/logs/:
reproduction_steps.log: complete build, setup, trigger, oracle, and cleanup transcript.source_identity.log: fixed commit, ticket source identities, bundled 7.0.2 archive checksum, and stable prepared repository path.image_identity.log: requested image digests and resolved Docker image IDs.network_boundary.log: distinct driver/provider and target identities plus isolated network state.vulnerable_setup.log: target version, image identity, mounts, stock plugin inventory, absent mu-plugins, initial user/oEmbed counts, grants, andlocal_infilestate.vulnerable_database_before.logandvulnerable_database_after.log: one-to-two user transition, fresh username/ID, administrator metadata, and oEmbed state.vulnerable_http_chain.log: full remote-chain JSON including generated administrator identity, normal-login result, plugin-upload result, and command response.vulnerable_command_response.log: target-originated command markers and exactwww-dataidentity.fixed_setup.log,fixed_http_chain.log, andfixed_database_after.log: unchanged-trigger failure before cache discovery and fixed postconditions.second_*logs andsecond_clean_run.log: independent clean-target repeat.bundle/repro/runtime_manifest.json: strict runtime evidence manifest written on every attempt.
Fresh current-run excerpts from the final two consecutive script executions include:
administrator.id=2
administrator.roles=["administrator"]
normal_login_confirmed=true
plugin_upload_confirmed=true
PRUVA-RCE-BEGIN
PRUVA-CMD-MARKER
uid=33(www-data) gid=33(www-data) groups=33(www-data)
PRUVA-RCE-EXIT:0
The matching database evidence records user_count=2, admin=2:<generated username>, while each fixed control records user_count=1 and oembed_count=0. The unchanged fixed trigger raises oEmbed seed did not create a discoverable cache row, proving first divergence before cache discovery. logs/pass1/ preserves the preceding successful top-level execution; the root logs/ files are the second successful execution. Historical proof-carry data is not treated as evidence for this verdict.
Recommendations / Next Steps
- Upgrade affected installations to WordPress 7.0.2 or later.
- Preserve the batch parser invariant by appending exactly one matched-handler and validation entry for every parsed sub-request, including parse errors.
- Normalize every author include/exclude input with
wp_parse_id_list()before SQL construction, regardless of the original scalar/array shape. - Refuse top-level
serve_request()re-entry while the REST server is already dispatching; guard bothrest_api_loaded()and the server entry point. - Add regression coverage for malformed entries at every batch position, scalar/list query-parameter forms, nested batch bodies, and dynamic status/type hooks reached during privileged context windows.
- Add end-to-end tests asserting that the unchanged 7.0.1 trigger cannot create oEmbed cache state, users, or plugin files on fixed releases.
Additional Notes
- The final proof uses the real stock HTTP/REST, login, and plugin-upload boundaries; no sanitizer, direct parser harness, or source-only oracle is used.
- The exploit driver performs no direct database write and receives no owner password or database credential.
- The oEmbed service is an isolated provider that returns valid bounded iframe HTML; it does not fabricate the command marker or privileged state.
- The vulnerable target uses no modified WordPress tree. The fixed control intentionally overlays the complete exact 7.0.2 source onto the same pinned official 7.0.1 PHP/Apache base.
- Container names are randomized and cleanup is trapped, making the script safe to repeat. It also recreates both vulnerable and fixed targets internally for a second clean matrix.
- Idempotency is confirmed: the final script was executed twice consecutively from clean targets, both exits were zero, generated administrator usernames differed, and every vulnerable/fixed oracle passed. Each script execution also performs an internal clean teardown/recreation, yielding four fresh vulnerable successes and four fixed controls across the two required top-level runs.
CVE-2026-63030 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired. Phases: support · claim contract · reproduction · judge · variant analysis
Full session Replay every step — scrub the timeline or play it back.
docker ps --format '{{.ID}} {{.Image}} {{.Names}}' && docker version --format '{{.Server.Version}}'{"cwd":"/data/pruva/runs/abec77ca-14dc-4055-8ebb-ac80871618ee/bundle","duration_ms":106,"exit_code":0,"stderr":"","stdout":"a67e10b66441 wordpress:7.0.1-php8.2-apache pruva-wp2shell-pure701-wp\n4da94e135114 mysql:8.0 pruva-wp2shell-pure701-db\n7ad432ff37c7 wordpress:7.0.1-php8.2-apache pruva-wp2shell-clean702-wp\n9e5b16b7816c mysql:8.0 pruva-wp2shell-clean702-db\n580eee2cd9e6 wordpress:7.0.1-php8.2-apache pruva-wp2shell-clean701-wp\nde3c483d5ea2 mysql:8.0 pruva-wp2shell-clean701-db\ncfb483a5f5c7 wordpress:7.0.1-php8.2-apache pruva-wp2shell-rce-wp\n37f17b82740d mysql:8.0 pruva-wp2shell-rce-db\ncb7f7fc2eea0 athena-pruva-worker-sandbox:latest pruva-wp2shell-rce-lab\n0195d2fe98c5 pruva-cve-2026-42533-slice-vuln:local spray-one\nb8e9f07d4649 athena-pruva-worker-sandbox:latest athena-pruva-worker-glm52-gpt55\n6fe65842cc97 athena-pruva-worker-sandbox:latest athena-pruva-worker-kimi27-gpt55\n538e7090ed37 athena-pruva-worker-sandbox:latest athena-pruva-worker-glm52-gpt55-repro2\n970810b9df5d athena-pruva-worker-sandbox:latest athena-pruva-worker-repro-unicorn-gpt56-max\n8a584f46c1dc athena-pruva-worker-sandbox:latest athena-pruva-worker-unicorn-gpt55-xhigh-1\n71d1eb1b3c4c athena-pruva-worke… [truncated]Artifacts and Evidence for CVE-2026-63030
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-63030
FAQ: CVE-2026-63030
Is CVE-2026-63030 exploitable without authentication?
How does the CVE-2026-63030 exploit chain work?
How severe is CVE-2026-63030?
How can I reproduce CVE-2026-63030?
References for CVE-2026-63030
Authoritative sources for CVE-2026-63030 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.