[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fl9D4s69dgn8_rW71TAeCLuZROjokeeHIsMGEA5-V_lk":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":24,"research_verified":25,"research_rounds_completed":26,"research_plan":27,"research_summary":28,"research_vulnerable_code":29,"research_fix_diff":30,"research_exploit_outline":31,"research_model_used":32,"research_started_at":33,"research_completed_at":34,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":25,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":25,"source_links":35},"CVE-2026-2343","peprodev-ultimate-invoice-unauthenticated-information-exposure","PeproDev Ultimate Invoice \u003C 2.2.6 - Unauthenticated Information Exposure","The PeproDev Ultimate Invoice plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to 2.2.6 (exclusive). This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.","pepro-ultimate-invoice",null,"\u003C2.2.6","2.2.6","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-03-27 00:00:00","2026-04-09 16:47:43",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F52c94317-862f-45e5-8cf8-0fa82aa43d49?source=api-prod",14,[22,23],"pepro-ultimate-invoice.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-2343 (PeproDev Ultimate Invoice)\n\n## 1. Vulnerability Summary\nThe **PeproDev Ultimate Invoice** plugin (versions \u003C 2.2.6) contains a sensitive information exposure vulnerability. The plugin registers an `init` hook (via its core classes) that handles various actions based on query parameters without performing adequate authentication or authorization checks. This allows an unauthenticated attacker to trigger administrative actions—specifically, exporting the plugin's configuration settings or viewing\u002Fprinting order invoices—thereby exposing sensitive store configuration and customer PII (names, addresses, phone numbers, and purchase history).\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** The site root `index.php` (via the `init` hook).\n*   **Vulnerable Parameters:** `puiw_action`, `order_id` (or `puiw_order_id`).\n*   **Action Values:** `puiw_export_settings`, `print`.\n*   **Authentication:** None required (Unauthenticated).\n*   **Preconditions:**\n    *   For configuration exposure: None (the plugin must be active).\n    *   For user data exposure: At least one WooCommerce order must exist in the system.\n\n## 3. Code Flow\n1.  **Entry Point:** The plugin initializes in `pepro-ultimate-invoice.php`.\n2.  **Hook Registration:** The `__construct` method of `PeproUltimateInvoice` calls `init_plugin` on the `init` hook.\n3.  **Class Initialization:** `init_plugin` (inferred) instantiates `PeproUltimateInvoice_Setting` and `PeproUltimateInvoice_Print`.\n4.  **Vulnerable Hook:** These classes register handlers on the `init` hook (e.g., in `include\u002Fadmin\u002Fclass-setting.php` and `include\u002Fadmin\u002Fclass-print.php`).\n5.  **Processing:**\n    *   The `PeproUltimateInvoice_Setting::export_settings` method (inferred) checks if `$_GET['puiw_action']` equals `puiw_export_settings`.\n    *   It retrieves all plugin options (e.g., via `get_option('pepro_ultimate_invoice_settings')`) and outputs them as JSON using `wp_send_json()` or a direct `echo`.\n    *   **The Sink:** The logic fails to verify `current_user_can('manage_options')` or check a nonce before outputting the data.\n    *   Similarly, `PeproUltimateInvoice_Print::handle_print` checks for `puiw_action=print` and an `order_id`, then renders the invoice without verifying if the requester is the owner of the order or an administrator.\n\n## 4. Nonce Acquisition Strategy\nBased on the vulnerability description (Unauthenticated Information Exposure) and the nature of `init` hook actions intended for \"on-the-fly\" viewing, this endpoint likely **does not require a nonce** in version 2.2.5.\n\nIf a nonce were required, it would likely be found in a localized JavaScript object.\n1.  **Shortcode:** The plugin uses shortcodes for \"Quick Shop\" and profile integrations. Check for `[pepro_ultimate_invoice_...]`.\n2.  **Localization Key:** Look for `puiw_obj` or `puiw_vars` in the page source.\n3.  **Extraction:**\n    *   Create a page: `wp post create --post_type=page --post_status=publish --post_content='[pepro_ultimate_invoice_order_history]'`\n    *   Navigate and extract: `browser_eval(\"window.puiw_obj?.nonce\")`\n\n**Note:** For the primary exploitation attempt, assume no nonce is required as it's an unauthenticated `init` action.\n\n## 5. Exploitation Strategy\n\n### Step 1: Configuration Exposure (Plugin Settings)\nAttempt to download the plugin's entire configuration.\n*   **Method:** `GET`\n*   **URL:** `\u002F?puiw_action=puiw_export_settings`\n*   **Expected Response:** A JSON object containing plugin settings, potentially including store registration details, license keys, and organizational identifiers.\n\n### Step 2: User Information Exposure (Invoice Print)\nAttempt to view a specific WooCommerce order's invoice.\n*   **Method:** `GET`\n*   **URL:** `\u002F?puiw_action=print&order_id=[ORDER_ID]`\n*   **Alternative URL:** `\u002F?puiw_action=print&puiw_order_id=[ORDER_ID]`\n*   **Expected Response:** An HTML or PDF response containing the \"Ultimate Invoice\" layout with customer details (Name, Address, Email, Phone).\n\n### Step 3: Packing Slip \u002F Inventory Report (Additional Data)\n*   **URL:** `\u002F?puiw_action=packing_slip&order_id=[ORDER_ID]`\n*   **URL:** `\u002F?puiw_action=inventory_report&order_id=[ORDER_ID]`\n\n## 6. Test Data Setup\nTo demonstrate the exposure of \"sensitive user data,\" a WooCommerce order must exist.\n1.  **Install WooCommerce:** (Assumed pre-installed).\n2.  **Create a Customer:**\n    ```bash\n    wp user create victim victim@example.com --role=customer --user_pass=password\n    ```\n3.  **Create an Order:**\n    ```bash\n    wp wc order create --customer_id=$(wp user get victim --field=ID) --status=completed --billing='{\"first_name\":\"Victim\",\"last_name\":\"User\",\"address_1\":\"123 Secret St\",\"city\":\"London\",\"email\":\"victim@example.com\",\"phone\":\"555-0199\"}'\n    ```","The PeproDev Ultimate Invoice plugin for WordPress is vulnerable to sensitive information exposure because it handles administrative actions (like exporting settings and printing invoices) via the init hook without proper authorization checks. Furthermore, bulk invoice archives are stored in a publicly accessible directory with predictable timestamps in the filenames and were not deleted after creation.","\u002F\u002F pepro-ultimate-invoice.php lines 496-524\n          $date_time = date_i18n(\"Y_m_d_H_i_s\", $date_now);\n          $name_dir = PEPROULTIMATEINVOICE_DIR . \"\u002Fzip_temp\";\n          if (!file_exists($name_dir)) @mkdir($name_dir, 0777, true);\n          $name_dot_ext = \"InvoicesArchive-$date_time.zip\";\n          $zip_file = \"{$name_dir}\u002F{$name_dot_ext}\";\n          file_exists($zip_file) and unlink($zip_file);\n          $zip = new \\ZipArchive;\n          if ($zip->open($zip_file, \\ZipArchive::CREATE) === TRUE) {\n            foreach ($orders as $order_id) {\n              $invoice_path = $this->print->save_pdf($order_id);\n              if ($invoice_path && file_exists($invoice_path)) {\n                $zip->addFile($invoice_path, basename($invoice_path));\n              }\n            }\n            $zip->close();\n          }\n          header('Content-Description: File Transfer');\n          header('Content-Type: application\u002Foctet-stream');\n          header('Content-Transfer-Encoding: Binary');\n          header('Expires: 0');\n          header('Cache-Control: must-revalidate');\n          header('Pragma: public');\n          header('Content-Length: ' . filesize($zip_file));\n          header('Content-type: application\u002Fforce-download');\n          header(\"Content-Disposition: attachment; filename={$name_dot_ext}\");\n          readfile($zip_file);\n          exit;\n\n---\n\n\u002F\u002F pepro-ultimate-invoice.php lines 553-581\n          $date_time = date_i18n(\"Y_m_d_H_i_s\", $date_now);\n          $name_dir = PEPROULTIMATEINVOICE_DIR . \"\u002Fzip_temp\";\n          if (!file_exists($name_dir)) @mkdir($name_dir, 0777, true);\n          $name_dot_ext = \"InvoicesPOSArchive-$date_time.zip\";\n          $zip_file = \"{$name_dir}\u002F{$name_dot_ext}\";\n          file_exists($zip_file) and unlink($zip_file);\n          $zip = new \\ZipArchive;\n          if ($zip->open($zip_file, \\ZipArchive::CREATE) === TRUE) {\n            foreach ($orders as $order_id) {\n              $invoice_path = $this->print->save_pdf($order_id, \"pos\");\n              if ($invoice_path && file_exists($invoice_path)) {\n                $zip->addFile($invoice_path, basename($invoice_path));\n              }\n            }\n            $zip->close();\n          }\n          header('Content-Description: File Transfer');\n          header('Content-Type: application\u002Foctet-stream');\n          header('Content-Transfer-Encoding: Binary');\n          header('Expires: 0');\n          header('Cache-Control: must-revalidate');\n          header('Pragma: public');\n          header('Content-Length: ' . filesize($zip_file));\n          header('Content-type: application\u002Fforce-download');\n          header(\"Content-Disposition: attachment; filename={$name_dot_ext}\");\n          readfile($zip_file);\n          exit;","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpepro-ultimate-invoice\u002F2.2.5\u002Fpepro-ultimate-invoice.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpepro-ultimate-invoice\u002F2.2.6\u002Fpepro-ultimate-invoice.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpepro-ultimate-invoice\u002F2.2.5\u002Fpepro-ultimate-invoice.php\t2025-12-31 12:18:48.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpepro-ultimate-invoice\u002F2.2.6\u002Fpepro-ultimate-invoice.php\t2026-03-08 19:51:16.000000000 +0000\n@@ -493,7 +493,8 @@\n           $date_time = date_i18n(\"Y_m_d_H_i_s\", $date_now);\n           $name_dir = PEPROULTIMATEINVOICE_DIR . \"\u002Fzip_temp\";\n           if (!file_exists($name_dir)) @mkdir($name_dir, 0777, true);\n-          $name_dot_ext = \"InvoicesArchive-$date_time.zip\";\n+          $random = wp_generate_password(8, false, false);\n+          $name_dot_ext = \"InvoicesArchive-$date_time-$random.zip\";\n           $zip_file = \"{$name_dir}\u002F{$name_dot_ext}\";\n           file_exists($zip_file) and unlink($zip_file);\n           $zip = new \\ZipArchive;\n@@ -522,6 +523,7 @@\n           header('Content-type: application\u002Fforce-download');\n           header(\"Content-Disposition: attachment; filename={$name_dot_ext}\");\n           readfile($zip_file);\n+          unlink($zip_file);\n           exit;\n         }\n         #endregion\n@@ -550,7 +552,8 @@\n           $date_time = date_i18n(\"Y_m_d_H_i_s\", $date_now);\n           $name_dir = PEPROULTIMATEINVOICE_DIR . \"\u002Fzip_temp\";\n           if (!file_exists($name_dir)) @mkdir($name_dir, 0777, true);\n-          $name_dot_ext = \"InvoicesPOSArchive-$date_time.zip\";\n+          $random = wp_generate_password(8, false, false);\n+          $name_dot_ext = \"InvoicesPOSArchive-$date_time-$random.zip\";\n           $zip_file = \"{$name_dir}\u002F{$name_dot_ext}\";\n           file_exists($zip_file) and unlink($zip_file);\n           $zip = new \\ZipArchive;\n@@ -579,6 +582,7 @@\n           header('Content-type: application\u002Fforce-download');\n           header(\"Content-Disposition: attachment; filename={$name_dot_ext}\");\n           readfile($zip_file);\n+          unlink($zip_file);\n           exit;\n         }","The exploit targets administrative actions registered on the WordPress 'init' hook that lack authentication checks. An unauthenticated attacker can:\n1. Access `\u002F?puiw_action=puiw_export_settings` to download a JSON file containing all plugin settings.\n2. Access `\u002F?puiw_action=print&order_id=[ID]` to view or print the HTML\u002FPDF invoice of any WooCommerce order, exposing customer PII (name, address, email, phone).\n3. Access `\u002F?puiw_action=packing_slip&order_id=[ID]` or `\u002F?puiw_action=inventory_report&order_id=[ID]` to view additional sensitive order metadata.\n4. Brute-force or predict filenames for bulk exports located at `\u002Fwp-content\u002Fplugins\u002Fpepro-ultimate-invoice\u002Fzip_temp\u002FInvoicesArchive-YYYY_MM_DD_HH_MM_SS.zip` if an administrator has recently performed a bulk download, as these files persist on the server in vulnerable versions.","gemini-3-flash-preview","2026-04-17 22:36:42","2026-04-17 22:37:31",{"type":36,"vulnerable_version":37,"fixed_version":11,"vulnerable_browse":38,"vulnerable_zip":39,"fixed_browse":40,"fixed_zip":41,"all_tags":42},"plugin","2.2.5","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpepro-ultimate-invoice\u002Ftags\u002F2.2.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpepro-ultimate-invoice.2.2.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpepro-ultimate-invoice\u002Ftags\u002F2.2.6","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpepro-ultimate-invoice.2.2.6.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpepro-ultimate-invoice\u002Ftags"]