CVE-2025-68606

PostX <= 5.0.3 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
5.0.4
Patched in
17d
Time to patch

Description

The Post Grid Gutenberg Blocks for News, Magazines, Blog Websites – PostX plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 5.0.3. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=5.0.3
PublishedDecember 21, 2025
Last updatedJanuary 6, 2026
Affected pluginultimate-post

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan outlines the steps for investigating and exploiting CVE-2025-68606, a sensitive information exposure vulnerability in the PostX (ultimate-post) plugin for WordPress. ### 1. Vulnerability Summary The PostX plugin (Post Grid Gutenberg Blocks) fails to properly restrict access to certain RES…

Show full research plan

This plan outlines the steps for investigating and exploiting CVE-2025-68606, a sensitive information exposure vulnerability in the PostX (ultimate-post) plugin for WordPress.

1. Vulnerability Summary

The PostX plugin (Post Grid Gutenberg Blocks) fails to properly restrict access to certain REST API endpoints or AJAX handlers. This lack of authorization allows unauthenticated users to query sensitive data, such as internal configuration settings or user-related information (e.g., usernames, emails, or metadata), which should be restricted to administrators.

2. Attack Vector Analysis

  • Vulnerable Component: REST API endpoints registered under the ultimate-post/v1 or postx/v1 namespaces.
  • Endpoint (Probable): wp-json/ultimate-post/v1/get-users or wp-json/ultimate-post/v1/settings.
  • Authentication: None (Unauthenticated).
  • HTTP Method: GET (most likely) or POST.
  • Preconditions: The plugin must be active. Some endpoints might only be exposed if specific blocks are used, though REST routes are usually registered globally on rest_api_init.

3. Code Flow (Inferred)

  1. Registration: The plugin uses the rest_api_init hook to register routes.
  2. Lack of Check: In register_rest_route(), the permission_callback is either:
    • Set to __return_true.
    • Missing entirely.
    • Uses a callback that doesn't verify current_user_can('manage_options').
  3. Data Retrieval: The callback function (e.g., get_all_users_callback) executes a WordPress query like get_users() or get_option() and returns the raw results as a JSON response.
  4. Exposure: An unauthenticated user hitting the endpoint receives the full JSON payload.

4. Nonce Acquisition Strategy

REST API endpoints in WordPress usually require a nonce (X-WP-Nonce header) for any request that is not a simple GET or if the user is logged in. However, for unauthenticated information exposure, the vulnerability often lies in endpoints that allow GET requests without a nonce or endpoints that accept the default wp_rest nonce which can be leaked.

If a nonce is required:

  1. Shortcode Identification: PostX is a Gutenberg block plugin. The most common way it enqueues scripts is through the [postx] or specific grid shortcodes/blocks.
  2. Page Creation:
    wp post create --post_type=page --post_status=publish --post_title="PostX Test" --post_content='<!-- wp:ultimate-post/post-grid /-->'
  3. Localization Variable: PostX typically localizes data into a JavaScript object. Look for postx_common_obj or ultimate_post_obj.
  4. Extraction:
    browser_navigate("http://localhost:8080/postx-test")
    browser_eval("window.postx_common_obj?.nonce || window.ultimate_post_obj?.nonce")

5. Exploitation Strategy

Step 1: Endpoint Discovery

Search the codebase to find exactly which REST routes are registered without proper permissions.

grep -r "register_rest_route" wp-content/plugins/ultimate-post/

Look for routes in the v1 namespace and check their permission_callback.

Step 2: Target Identification

Focus on functions like:

  • get_users
  • get_settings
  • get_all_posts
  • export_data

Step 3: Execution (HTTP Request)

Assuming the endpoint is wp-json/ultimate-post/v1/get-users:

GET /wp-json/ultimate-post/v1/get-users HTTP/1.1
Host: localhost:8080
Accept: application/json

If it requires a POST request or a nonce:

POST /wp-json/ultimate-post/v1/get-users HTTP/1.1
Host: localhost:8080
Content-Type: application/json
X-WP-Nonce: [EXTRACTED_NONCE]

{}

6. Test Data Setup

  1. Users: Create a few users with different roles.
    wp user create victim_admin admin@example.com --role=administrator --user_pass=password123
    wp user create victim_editor editor@example.com --role=editor
    
  2. Sensitive Options: (Optional) Add dummy sensitive data to plugin settings if a settings endpoint is found.
  3. Plugin Setup: Ensure PostX is active.
    wp plugin activate ultimate-post
    

7. Expected Results

  • Vulnerable: The response returns a 200 OK with a JSON array containing user objects (including user_login, user_email, display_name, and potentially ID).
  • Vulnerable (Settings): The response returns a 200 OK with internal plugin configurations, path disclosures, or license keys.
  • Secured: The response returns a 401 Unauthorized or 403 Forbidden with a message like "Sorry, you are not allowed to do that."

8. Verification Steps

After receiving the HTTP response, verify the data against the database:

# Compare the emails received in the JSON to the DB
wp user list --fields=user_email

9. Alternative Approaches

If the REST API is not the vector, check for unauthenticated AJAX actions:

  1. Search for AJAX: grep -r "wp_ajax_nopriv" wp-content/plugins/ultimate-post/.
  2. Check Callback: Inspect the function associated with the AJAX action for any current_user_can checks.
  3. Request: Use admin-ajax.php with the discovered action and nonce (if needed).
# Example AJAX request
http_request(
    url="http://localhost:8080/wp-admin/admin-ajax.php",
    method="POST",
    data={"action": "postx_get_sensitive_data", "nonce": "[NONCE]"}
)

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.