Age Verification & Identity Verification by Token of Trust <= 4.0.2 - Missing Authorization to Unauthenticated Information Exposure via 'tot_export_table' Parameter
Description
The Age Verification & Identity Verification by Token of Trust plugin for WordPress is vulnerable to unauthorized access in all versions up to and including 4.0.2. This is due to the handle_export_table() function being registered on the WordPress 'init' hook, which fires for all requests, including those from unauthenticated visitors, without any capability check. This makes it possible for unauthenticated attackers to download a CSV file containing sensitive WooCommerce donation data, including order dates, order IDs, charitable donation amounts, and admin-only order edit URLs, simply by visiting any page on the site with the 'tot_export_table' GET parameter set to a numeric value (0–3).
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
What Changed in the Fix
Changes introduced in v4.0.3
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-7558 ## 1. Vulnerability Summary The **Age Verification & Identity Verification by Token of Trust** plugin for WordPress (versions <= 4.0.2) suffers from a **Missing Authorization** vulnerability that leads to unauthenticated information exposure. The plugi…
Show full research plan
Exploitation Research Plan - CVE-2026-7558
1. Vulnerability Summary
The Age Verification & Identity Verification by Token of Trust plugin for WordPress (versions <= 4.0.2) suffers from a Missing Authorization vulnerability that leads to unauthenticated information exposure.
The plugin registers a data export function, handle_export_table(), on the WordPress init hook. This hook executes for every request, including those from unauthenticated visitors. The function lacks any capability checks (e.g., current_user_can('manage_options')) or CSRF nonce verification. Consequently, any user can trigger a CSV download containing sensitive WooCommerce donation data, including order IDs, dates, donation amounts, and internal admin URLs for editing orders.
2. Attack Vector Analysis
- Vulnerable Endpoint: Any WordPress URL (Frontend or Backend) as the logic is tied to the
inithook. - Vulnerable Parameter:
tot_export_table(GET). - Authentication Level: Unauthenticated (PR:N).
- Preconditions: WooCommerce must be installed and active, and there must be orders with the
tot_donation_valuemeta-data.
3. Code Flow
- Entry Point: During WordPress initialization, the
inithook is fired. - Hook Registration: In
integrations/woocommerce/class-donations.php, the__construct()method registers the callback:add_action( 'init', array( $this->hookHandler, 'handle_export_table' ) ); - Trigger:
handle_export_table()checks for the existence of thetot_export_tableGET parameter:public function handle_export_table() { if ( isset( $_GET['tot_export_table'] ) && is_numeric( $_GET['tot_export_table'] ) ) { $this->export_table_as_csv(); } } - Data Retrieval:
export_table_as_csv()callsself::get_tables(). - Query Logic:
get_tables()useswc_get_orders()with ameta_querylooking for orders wheretot_donation_value > 0. - Sink: The function
export_table_as_csv()generates a CSV, sets theContent-Type: text/csvheader, and outputs the file content viareadfile(), then callsexit().
4. Nonce Acquisition Strategy
No nonce is required for this exploit.
A review of integrations/woocommerce/class-donations.php confirms that neither handle_export_table() nor export_table_as_csv() performs any nonce validation (e.g., check_admin_referer or wp_verify_nonce). The vulnerability stems specifically from the lack of these security controls on a sensitive data export operation.
5. Exploitation Strategy
The exploit involves a simple GET request to the WordPress site with the targeting parameter.
- Step 1: Prepare a request to the site root with the
tot_export_tableparameter set to0(which corresponds to "All months" inget_default_tables_var()). - Tool:
http_request(Playwright). - Request Details:
- Method:
GET - URL:
http://<target-domain>/index.php?tot_export_table=0
- Method:
- Expected Response:
- Status: 200 OK
- Header:
Content-Type: text/csv - Header:
Content-Disposition: attachment; filename=tot_donations_...csv - Body: A CSV formatted string starting with
Date,Order number,Charitable amount,Order Url.
6. Test Data Setup
To verify the exploit, the environment must contain WooCommerce data:
- Install WooCommerce: Ensure the WooCommerce plugin is active.
- Create Orders: Create at least two WooCommerce orders.
- Inject Meta Data: Use WP-CLI to add the donation meta-key to the orders:
# Example for Order ID 123 wp post meta add 123 tot_donation_value 15.50 # Example for Order ID 124 wp post meta add 124 tot_donation_value 5.00 - Verify Setup: Check that the plugin's "View Donations" page (if accessible) would normally show these.
7. Expected Results
A successful exploit will return a raw CSV download. The content will look like this:
Date,Order number,Charitable amount,Order Url
"2023-10-27 10:00:00","123","$15.50","http://example.com/wp-admin/post.php?post=123&action=edit"
"2023-10-27 11:00:00","124","$5.00","http://example.com/wp-admin/post.php?post=124&action=edit"
8. Verification Steps
- Response Content: Verify the response body contains the string
Date,Order number,Charitable amount,Order Url. - Data Integrity: Compare the IDs and amounts in the CSV with the output of:
wp post meta get 123 tot_donation_value - Auth Status: Perform the request in an unauthenticated state (no session cookies) to confirm the "Missing Authorization" aspect.
9. Alternative Approaches
If index 0 ("All months") returns no data due to date filtering in get_tables(), attempt to use other table indices defined in get_default_tables_var():
?tot_export_table=1(Current month)?tot_export_table=2(Last month)?tot_export_table=3(Two months ago)
If the site uses a custom permalink structure that intercepts parameters at the root, try targeting admin-ajax.php instead (as init still fires there):
GET /wp-admin/admin-ajax.php?tot_export_table=0
Summary
The 'Age Verification & Identity Verification by Token of Trust' plugin for WordPress suffers from a missing authorization vulnerability due to an export handler registered on the 'init' hook. Because the handler lacks capability checks and CSRF protection, unauthenticated attackers can download CSV files containing sensitive WooCommerce donation data, including order IDs, donation amounts, and internal administration URLs.
Vulnerable Code
// integrations/woocommerce/class-donations.php line 97 public function __construct() { $this->hookHandler = HookHandler::getInstance( $this ); add_action( 'init', array( $this->hookHandler, 'handle_export_table' ) ); } public function handle_export_table() { if ( isset( $_GET['tot_export_table'] ) && is_numeric( $_GET['tot_export_table'] ) ) { $this->export_table_as_csv(); } } --- // integrations/woocommerce/class-donations.php line 111 public function export_table_as_csv() { $table_no = $_GET['tot_export_table']; $tables = self::get_tables(); if ( ! isset( $tables[ $table_no ] ) ) { return; } $table = $tables[ $table_no ]; // Define CSV filename $filename = 'tot_donations_' . time() . '.csv'; // Set CSV headers $header_row = array( 'Date', 'Order number', 'Charitable amount', 'Order Url' ); // ... (truncated)
Security Fix
@@ -30,7 +30,7 @@ <h3>Sum of Charitable donations: <?php echo esc_html( get_woocommerce_currency_symbol() . $table['sum'] ); ?></h3> <div class="tot-export-wrapper"> - <a href="?page=totsettings_donations&tot_export_table=<?php echo esc_attr( $key ); ?>" class="tot-btn-export"> + <a href="?page=totsettings_donations&tot_export_table=<?php echo esc_attr( $key ); ?>&tot_export_nonce=<?php echo esc_attr( wp_create_nonce( 'tot_export_table' ) ); ?>" class="tot-btn-export"> export </a> </div> @@ -97,16 +97,22 @@ public function __construct() { $this->hookHandler = HookHandler::getInstance( $this ); - add_action( 'init', array( $this->hookHandler, 'handle_export_table' ) ); + add_action( 'admin_init', array( $this->hookHandler, 'handle_export_table' ) ); } public function handle_export_table() { if ( isset( $_GET['tot_export_table'] ) && is_numeric( $_GET['tot_export_table'] ) ) { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return; + } + if ( ! isset( $_GET['tot_export_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['tot_export_nonce'] ), 'tot_export_table' ) ) { + return; + } $this->export_table_as_csv(); } } public function export_table_as_csv() { - $table_no = $_GET['tot_export_table']; + $table_no = intval( $_GET['tot_export_table'] ); $tables = self::get_tables(); if ( ! isset( $tables[ $table_no ] ) ) { return;
Exploit Outline
The exploit is executed by an unauthenticated attacker by sending a standard GET request to any WordPress endpoint (frontend or backend). By providing the 'tot_export_table' parameter with a numeric value (0, 1, 2, or 3), the attacker triggers the handle_export_table() callback. Since this callback is hooked to 'init' and lacks both capability checks and nonce validation, the server will process the request, generate a CSV containing WooCommerce order data (filtered by the presence of a donation meta-key), and return it as a file download. No special payload beyond the GET parameter is required.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.