Breadcrumb NavXT <= 7.5.0 - Missing Authorization to Sensitive Information Exposure
Description
The Breadcrumb NavXT plugin for WordPress is vulnerable to authorization bypass through user-controlled key in versions up to and including 7.5.0. This is due to the Gutenberg block renderer trusting the $_REQUEST['post_id'] parameter without verification in the includes/blocks/build/breadcrumb-trail/render.php file. This makes it possible for unauthenticated attackers to enumerate and view breadcrumb trails for draft or private posts by manipulating the post_id parameter, revealing post titles and hierarchy that should remain hidden.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=7.5.0Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-13842 (Breadcrumb NavXT) ## 1. Vulnerability Summary The **Breadcrumb NavXT** plugin (versions <= 7.5.0) contains an authorization bypass vulnerability in its Gutenberg block rendering logic. The file `includes/blocks/build/breadcrumb-trail/render.php` process…
Show full research plan
Exploitation Research Plan: CVE-2025-13842 (Breadcrumb NavXT)
1. Vulnerability Summary
The Breadcrumb NavXT plugin (versions <= 7.5.0) contains an authorization bypass vulnerability in its Gutenberg block rendering logic. The file includes/blocks/build/breadcrumb-trail/render.php processes the rendering of the "Breadcrumb Trail" block. This file checks for a post_id within the $_REQUEST superglobal and uses it to generate the breadcrumb trail without verifying if the current user has permission to view the post associated with that ID.
This allows unauthenticated attackers to view the breadcrumb hierarchy and titles of Draft, Private, or Password Protected posts by providing their IDs, leading to sensitive information exposure.
2. Attack Vector Analysis
- Endpoint: Any public-facing WordPress page or post that contains the Breadcrumb NavXT "Breadcrumb Trail" block.
- Vulnerable Parameter:
post_id(via$_GET,$_POST, or$_REQUEST). - Authentication: None (Unauthenticated).
- Preconditions:
- The plugin Breadcrumb NavXT (<= 7.5.0) must be active.
- At least one public page must contain the
breadcrumb-navxt/breadcrumb-trailGutenberg block. - The attacker needs to guess or enumerate Post IDs (standard WordPress integer increments).
3. Code Flow
- Entry Point: A visitor requests a page that includes the Breadcrumb NavXT block.
- Hook Registration: The block is registered via
register_block_type(likely inbreadcrumb-navxt.phpor a block initialization file), pointing toincludes/blocks/build/breadcrumb-trail/render.phpas therender_callback. - Vulnerable Logic (in
render.php):- The code retrieves the ID for which to generate breadcrumbs.
- It prioritizes
$_REQUEST['post_id'](or a similar key) if present. - Example (Inferred):
$p_id = isset($_REQUEST['post_id']) ? intval($_REQUEST['post_id']) : get_the_ID(); // The plugin then initializes the breadcrumb trail for $p_id $breadcrumb_trail = new bcn_breadcrumb_trail(); $breadcrumb_trail->fill($p_id); echo $breadcrumb_trail->display();
- Sink: The
fill()anddisplay()methods of thebcn_breadcrumb_trailclass generate HTML containing the post title and its parent hierarchy. Since nocurrent_user_can('read_post', $p_id)check is performed inrender.php, the data is rendered and returned to the unauthenticated user.
4. Nonce Acquisition Strategy
According to the vulnerability description, this is an Authorization Bypass through User-Controlled Key during a block render.
- Requirement: This specific vulnerability usually does not require a nonce because it exploits the standard rendering of a block on a public page. Block renderers (
render.php) are executed by WordPress core when the content is parsed for display. - Verification: If the exploit fails, I will check if the plugin localizes any variables for the block.
- Potential variable names:
bcn_block_optionsor similar. - However, for an unauthenticated information exposure via query parameters, a nonce is highly unlikely.
- Potential variable names:
5. Exploitation Strategy
Step-by-Step Plan:
- Locate Target ID: Enumerate or use a known ID of a private/draft post.
- Identify Target Page: Locate a public page containing the
[breadcrumb-trail]block or the equivalent Gutenberg block. - Send Exploit Request: Perform a GET request to the public page, appending the
post_idof the private post. - Extract Data: Parse the HTML response to find the breadcrumb trail and extract the title of the private post.
Specific HTTP Request:
GET /?p=[PUBLIC_PAGE_ID]&post_id=[PRIVATE_POST_ID] HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
6. Test Data Setup
- Create Private Post:
wp post create --post_type=post --post_title="SECRET_INTERNAL_PROJECT" --post_status=private --post_content="Confidential info"- Record the ID (e.g.,
123).
- Create Public Page with Block:
wp post create --post_type=page --post_title="Public Breadcrumb Page" --post_status=publish --post_content='<!-- wp:breadcrumb-navxt/breadcrumb-trail /-->'- Record the ID (e.g.,
456).
- Configure Plugin: Ensure Breadcrumb NavXT is activated.
wp plugin activate breadcrumb-navxt
7. Expected Results
- Unauthenticated Success: The HTTP response for the public page (
?p=456&post_id=123) will contain the string"SECRET_INTERNAL_PROJECT"within the breadcrumb HTML structure (typically inside<span>or<li>tags generated by the plugin). - Normal Behavior (Expected for Patched): The breadcrumb trail should either ignore the
post_idparameter or perform a capability check, showing breadcrumbs for page456only.
8. Verification Steps
- Check Response Body:
- Look for the title of the private post created in Step 6.
- Verify via WP-CLI:
- Confirm the post with that title is indeed
private:wp post get [PRIVATE_ID] --field=post_status
- Confirm the post with that title is indeed
- Confirm Privacy:
- Verify that a direct request to
/?p=[PRIVATE_ID]returns a 404 or a login redirect, proving the post is not normally accessible.
- Verify that a direct request to
9. Alternative Approaches
- Enumeration Script: If the post ID is unknown, a simple loop from 1 to 100 on the
post_idparameter can be used to discover hidden content. - REST API Check: Check if the Gutenberg block
render_callbackcan be reached via the REST APIautosaveorrender-blockendpoints, which sometimes expose similar flaws:GET /wp-json/wp/v2/block-renderer/breadcrumb-navxt/breadcrumb-trail?context=edit&post_id=[PRIVATE_ID]
(Note: This usually requires 'edit' permissions, whereas therender.phpflaw is reported as unauthenticated). - POST Request: Try sending
post_idin a POST body to the same URL if GET is filtered.
Summary
The Breadcrumb NavXT plugin for WordPress is vulnerable to an information disclosure flaw due to missing authorization checks in its Gutenberg block renderer. Unauthenticated attackers can manipulate the 'post_id' parameter in a request to a public page containing the breadcrumb block, forcing the plugin to render and reveal the titles and hierarchy of private or draft posts.
Vulnerable Code
// includes/blocks/build/breadcrumb-trail/render.php // Inferred logic where the block renderer retrieves the post ID from the request if ( isset( $_REQUEST['post_id'] ) ) { $p_id = (int) $_REQUEST['post_id']; } else { $p_id = get_the_ID(); } $breadcrumb_trail = new bcn_breadcrumb_trail(); // The trail is populated using the user-controlled ID without checking if the user can read that post $breadcrumb_trail->fill( $p_id ); echo $breadcrumb_trail->display();
Security Fix
@@ -13,7 +13,12 @@ $p_id = 0; if ( isset( $_REQUEST['post_id'] ) ) { - $p_id = (int) $_REQUEST['post_id']; + $potential_id = (int) $_REQUEST['post_id']; + if ( get_post_status( $potential_id ) === 'publish' || current_user_can( 'read_post', $potential_id ) ) { + $p_id = $potential_id; + } else { + $p_id = get_the_ID(); + } } else { $p_id = get_the_ID(); }
Exploit Outline
The exploit targets the Gutenberg 'Breadcrumb Trail' block rendered on any public-facing page. An unauthenticated attacker identifies a page containing this block and appends a 'post_id' parameter to the URL (e.g., ?post_id=123). By iterating through potential post IDs, the attacker can cause the block to render the breadcrumb trail for posts they should not have access to, such as those in 'Draft' or 'Private' status. The resulting HTML response contains the sensitive post title and its organizational hierarchy (categories/parents) in the breadcrumb output.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.