CVE-2026-2696

Export All URLs < 5.1 - Unauthenticated Information Exposure

highExposure of Sensitive Information to an Unauthorized Actor
7.5
CVSS Score
7.5
CVSS Score
high
Severity
5.1
Patched in
8d
Time to patch

Description

The Export All URLs plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to 5.1 (exclusive). 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:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<5.1
PublishedApril 2, 2026
Last updatedApril 9, 2026
Affected pluginexport-all-urls

What Changed in the Fix

Changes introduced in v5.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-2696 (Export All URLs) ## 1. Vulnerability Summary The **Export All URLs** plugin (versions < 5.1) is vulnerable to **Unauthenticated Information Exposure**. The plugin fails to perform proper capability checks (e.g., `current_user_can('manage_options')`) or n…

Show full research plan

Exploitation Research Plan: CVE-2026-2696 (Export All URLs)

1. Vulnerability Summary

The Export All URLs plugin (versions < 5.1) is vulnerable to Unauthenticated Information Exposure. The plugin fails to perform proper capability checks (e.g., current_user_can('manage_options')) or nonce verification on the code path that triggers data exports. Consequently, any unauthenticated actor can trigger a CSV export or a screen display of sensitive site data, including post IDs, titles, private/draft post information, and author usernames/IDs.

2. Attack Vector Analysis

  • Endpoint: Likely wp-admin/admin-ajax.php or any front-end page (triggering an init or admin_init hook).
  • Action/Parameter: The export is likely triggered by a specific request parameter such as eau_export, export_all_urls, or a similarly named variable handled during initialization.
  • Authentication: None required (Unauthenticated).
  • Preconditions: The plugin must be active. The attacker needs to identify the exact query parameters used to define the export scope (post types, statuses).

3. Code Flow

  1. Entry Point: An unauthenticated request is made to the WordPress site (e.g., GET /?eau_export=1 or GET /wp-admin/admin-ajax.php?eau_export=1).
  2. Hook Execution: WordPress triggers the init or admin_init hooks.
  3. Vulnerable Handler: A function (likely located in extract-all-urls-settings.php or registered in extract-all-urls.php) checks for the presence of the export trigger parameter ($_GET['eau_export'] or similar).
  4. Missing Authorization: The handler proceeds to execute the export logic without verifying if the user has the Constants::PLUGIN_SETTINGS_PAGE_CAPABILITY or is logged in.
  5. Information Leak: The handler queries the database (using get_posts or $wpdb) for the requested data (including post_status => 'private' or 'any') and either streams the CSV content directly to the response or provides a link to a generated file.

4. Nonce Acquisition Strategy

This vulnerability is classified as Unauthenticated, which typically implies that:

  1. A nonce check is entirely missing in the export trigger path.
  2. The check_admin_referer or check_ajax_referer is called but the result is not checked or is bypassed.

Verification Steps for Nonce Requirement:

  1. The agent should first attempt the exploit without a nonce.
  2. If it fails, search the source code for check_ajax_referer, check_admin_referer, or wp_verify_nonce in proximity to the export logic.
  3. If a nonce is required, check if it is localized via wp_localize_script in eau-script (registered in extract-all-urls.php line 44).
  4. How to extract if required:
    • Note: Since this is unauthenticated, the script might not be enqueued on the frontend. If it is, use:
    • browser_eval("window.eau_script_vars?.nonce") (Verify the actual variable name in the source).
    • If nonces are only in the admin area, but the export handler is in admin_init, the handler may be accessible without a nonce via admin-ajax.php.

5. Exploitation Strategy

Step 1: Discovery

Search the plugin directory for the export trigger.

grep -rn "add_action" .
grep -rn "init" . | grep "export"
grep -rn "eau_export" .

Step 2: Parameter Identification

Identify the parameters used to filter data. Based on the readme.txt, look for:

  • post_type (e.g., post, page)
  • post_status (e.g., private, draft, publish)
  • eau_fields (Array of fields like post_id, post_title, author)
  • export_type (Value csv or display)

Step 3: Trigger Information Exposure

Use the http_request tool to send a request. We will attempt to export Private posts to prove sensitive exposure.

Payload (Targeting admin_init via admin-ajax.php):

POST /wp-admin/admin-ajax.php?eau_export=true HTTP/1.1
Content-Type: application/x-www-form-urlencoded

post_type=post&post_status[]=private&post_status[]=publish&eau_fields[]=post_id&eau_fields[]=post_title&eau_fields[]=post_url&eau_fields[]=author&export_type=csv&eau_submit=Export+Now

Payload (Targeting init via Frontend):

GET /?eau_export=1&post_type=post&post_status=private&export_type=csv HTTP/1.1

6. Test Data Setup

To confirm the exploit, the test environment must have:

  1. Export All URLs plugin (v5.0) installed and activated.
  2. A Private Post created by an administrator:
    • wp post create --post_type=post --post_title="Secret Sensitive Data" --post_status=private --post_author=1
  3. A Draft Post:
    • wp post create --post_type=post --post_title="Draft Internal Strategy" --post_status=draft

7. Expected Results

  • Response Code: 200 OK
  • Headers: Content-Type: text/csv or Content-Disposition: attachment; filename=...
  • Body Content: The CSV data containing the "Secret Sensitive Data" post title and URL.
  • Success Indicator: The ability to see titles and metadata of private and draft posts without any cookies or Authorization headers.

8. Verification Steps

After the HTTP request, verify the data matches the database:

  1. wp post list --post_status=private --fields=ID,post_title
  2. Compare the output with the CSV data captured during the exploit.
  3. Check if any user information was leaked: wp user list --fields=ID,user_login.

9. Alternative Approaches

  • Display Mode: If export_type=csv fails or filters output, try export_type=display. The plugin might echo the data directly into the HTML response instead of generating a file.
  • Filename Brute Force: If the plugin generates a random CSV but doesn't stream it, check the wp-content/uploads/ directory for a folder named extract-all-urls or similar. Even if the filename is random, if the directory listing is enabled or the generation logic is predictable (e.g., based on microtime()), the file can be accessed.
  • User Export: Check if post_type=user (inferred) is supported, which would leak user emails and password hashes.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Export All URLs plugin for WordPress is vulnerable to unauthenticated information exposure because it fails to perform capability checks or nonce verification on the code path that triggers data exports. This allows an unauthorized actor to trigger a CSV export or screen display of sensitive site data, including post IDs, titles, and metadata for private or draft posts.

Vulnerable Code

/* The vulnerable logic is located in the export handler, typically found in extract-all-urls-settings.php or a hook in extract-all-urls.php. It lacks check_admin_referer() and current_user_can() checks before processing exports. */

// Logical representation of the vulnerability as described in research:
if (isset($_REQUEST['eau_export'])) {
    // Missing: if (!current_user_can('manage_options')) { wp_die(); }
    // Missing: check_admin_referer('eau_export_action');

    $post_type = $_POST['post_type'];
    $post_status = $_POST['post_status']; // Can be set to 'private' or 'draft' by attacker
    
    // ... logic to query posts and generate CSV output ...
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.0/extract-all-urls.php /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.1/extract-all-urls.php
--- /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.0/extract-all-urls.php	2025-02-10 11:13:08.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.1/extract-all-urls.php	2026-03-09 11:32:48.000000000 +0000
@@ -4,7 +4,7 @@
 Plugin Name: Export All URLs
 Plugin URI: https://AtlasGondal.com/
 Description: This plugin enables you to extract information such as Title, URL, Categories, Tags, Author, as well as Published and Modified dates for built-in post types (e.g., post, page) or any other custom post types present on your site. You have the option to display the output in the dashboard or export it as a CSV file. This can be highly beneficial for tasks like migration, SEO analysis, and security audits.
-Version: 5.0
+Version: 5.1
 Author: Atlas Gondal
 Author URI: https://AtlasGondal.com/
 License: GPL v2 or higher
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.0/readme.txt /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.1/readme.txt
--- /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.0/readme.txt	2025-12-13 11:23:46.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/export-all-urls/5.1/readme.txt	2026-03-09 11:32:48.000000000 +0000
@@ -3,8 +3,8 @@
 Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YWT3BFURG6SGS&source=url
 Tags: extract urls, export urls, links, get links, get urls, custom post type urls, see links, extract title, export title, export post title, export title and url, export category, utilities, export, csv
 Requires at least: 3.1
-Tested up to: 6.9
-Stable tag: 5.0
+Tested up to: 6.9.1
+Stable tag: 5.1
 Requires PHP: 5.4
 License: GPLv2 or later
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -137,6 +137,10 @@
 
 == Changelog ==
 
+= 5.1 =
+* Improvement - strengthened csv file name to prevent unauthorized discovery
+* Compatibility - tested with Wordpress 6.9.1
+
 = 5.0 =
 * New - additional export fields added (status, category urls, tag urls)
 * New - allows multiple post status selection
@@ -241,8 +245,6 @@
 
 == Upgrade Notice ==
 
-= 5.0 =
-* New - additional export fields added (status, category urls, tag urls)
-* New - allows multiple post status selection
-* Improvement - few backend refinements to improve performance
-* Compatibility - tested with Wordpress 6.7.1
+= 5.1 =
+* Improvement - strengthened csv file name to prevent unauthorized discovery
+* Compatibility - tested with Wordpress 6.9.1

Exploit Outline

An unauthenticated attacker can exploit this vulnerability by sending a GET or POST request to an administrative endpoint that triggers the export logic, such as /wp-admin/admin-ajax.php. By including the 'eau_export' parameter and defining desired filters like 'post_type=post' and 'post_status[]=private', the attacker forces the plugin to process an export without requiring a login or administrative session. The server will respond with the exported CSV data or provide a link to a generated file containing sensitive titles, IDs, and metadata of non-public posts.

Check if your site is affected.

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