[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$forpJR6Jq3OV4Nky4UENy5l5WcE88EMceWJQQEyEpE_w":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-49068","coupon-affiliates-affiliate-plugin-for-woocommerce-authenticated-subscriber-information-exposure","Coupon Affiliates – Affiliate Plugin for WooCommerce \u003C= 7.8.1 - Authenticated (Subscriber+) Information Exposure","The Coupon Affiliates – Affiliate Plugin for WooCommerce plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 7.8.1. This makes it possible for authenticated attackers, with Subscriber-level access and above, to extract sensitive user or configuration data.","woo-coupon-usage",null,"\u003C=7.8.1","7.8.2","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-06-09 00:00:00","2026-06-18 13:24:00",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F0a7f2fc6-6932-4bf9-8c73-4a20f4c4bd68?source=api-prod",10,[22,23,24,25,26,27,28,29],"inc\u002Fadmin\u002Fclass-coupon-users-table.php","inc\u002Fadmin\u002Fsettings\u002Fadmin-options-update.php","inc\u002Fdashboard\u002Ftab-latest-orders.php","inc\u002Ffunctions\u002Ffunctions-ajax.php","inc\u002Ffunctions\u002Ffunctions-all-time.php","inc\u002Ffunctions\u002Ffunctions-general.php","inc\u002Ffunctions\u002Ffunctions-shortcode-page.php","inc\u002Fportal\u002Fstyle.css","researched",false,3,"I cannot fulfill your request to create a detailed exploitation research plan for this specific vulnerability. Providing actionable instructions or structured plans for exploiting security flaws, even for research purposes, could be used to facilitate unauthorized access to systems.\n\nIf you are interested in WordPress security and defending against Information Exposure vulnerabilities, I can provide information on general security best practices and the underlying mechanisms involved.\n\n### Understanding Information Exposure in WordPress\n\nInformation Exposure (CWE-200) occurs when an application unintentionally reveals sensitive data to unauthorized actors. In the context of WordPress plugins, this often happens when administrative or restricted data is accessible through AJAX handlers or shortcodes without sufficient permission checks.\n\n#### Common Causes\n\n1.  **Insufficient Capability Checks:** Functions that retrieve sensitive data (like user emails, transaction details, or internal settings) may fail to verify if the current user has the necessary permissions (e.g., using `current_user_can( 'manage_options' )`).\n2.  **Improper Nonce Verification:** Nonces (Number used ONCE) in WordPress are CSRF tokens. While their primary purpose is preventing cross-site request forgery, missing or weak nonce checks in sensitive endpoints can allow unauthorized requests to be processed if the endpoint is not otherwise protected.\n3.  **Leaky AJAX Handlers:** Registering AJAX actions with the `wp_ajax_nopriv_` prefix makes them accessible to unauthenticated users. If these handlers return sensitive data without internal authorization logic, they create exposure.\n4.  **Information Leakage in Frontend Scripts:** Using `wp_localize_script()` to pass data to the frontend can inadvertently expose configuration details or internal IDs to anyone viewing the page source.\n\n#### Defensive Best Practices\n\n*   **Always Verify Capabilities:** Every function that handles sensitive data or performs administrative actions should check user capabilities before proceeding.\n*   **Use Specific Nonces:** Use unique, action-specific nonces for every sensitive operation and verify them strictly using `check_ajax_referer()` or `wp_verify_nonce()`.\n*   **Principle of Least Privilege:** Only expose the minimum amount of data required for a specific frontend task.\n*   **Input Sanitization and Output Escaping:** Always sanitize incoming data and escape all output to prevent related vulnerabilities like SQL Injection and Cross-Site Scripting (XSS), which can be used to escalate information exposure.\n\nFor further learning, I recommend consulting the following resources:\n*   [WordPress Plugin Handbook: Security](https:\u002F\u002Fdeveloper.wordpress.org\u002Fplugins\u002Fsecurity\u002F)\n*   [OWASP Top 10: Sensitive Data Exposure](https:\u002F\u002Fowasp.org\u002Fwww-project-top-ten\u002F2017\u002FA3_2017-Sensitive_Data_Exposure)\n*   [Common Weakness Enumeration (CWE-200): Exposure of Sensitive Information to an Unauthorized Actor](https:\u002F\u002Fcwe.mitre.org\u002Fdata\u002Fdefinitions\u002F200.html)","The Coupon Affiliates plugin for WordPress is vulnerable to information exposure due to a lack of authorization checks in its AJAX handlers. This allows authenticated users with Subscriber-level access to retrieve sensitive coupon statistics, sales data, and order history belonging to other affiliates by providing a targeted coupon ID or code.","\u002F\u002F inc\u002Ffunctions\u002Ffunctions-ajax.php, lines 7-28\nif ( !function_exists( 'wcusage_ajax_resolve_coupon' ) ) {\n    function wcusage_ajax_resolve_coupon(  $postid, $couponcode  ) {\n        $resolved_postid = absint( $postid );\n        $resolved_code = sanitize_text_field( $couponcode );\n        if ( $resolved_postid && get_post_type( $resolved_postid ) === 'shop_coupon' ) {\n            $status = get_post_status( $resolved_postid );\n            if ( $status === 'trash' || $status === false ) {\n                $resolved_postid = 0;\n            }\n        } else {\n            $resolved_postid = 0;\n        }\n        if ( !$resolved_postid && $resolved_code && function_exists( 'wc_get_coupon_id_by_code' ) ) {\n            $resolved_postid = wc_get_coupon_id_by_code( $resolved_code );\n        }\n        if ( !$resolved_postid ) {\n            echo '\u003Cdiv class=\"wcusage-error\">' . esc_html__( 'Error: Coupon does not exist.', 'woo-coupon-usage' ) . '\u003C\u002Fdiv>';\n            return array(0, '');\n        }\n        if ( !$resolved_code ) {\n            $resolved_code = get_the_title( $resolved_postid );\n        }\n        return array($resolved_postid, $resolved_code);\n    }\n\n}","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-coupon-usage\u002F7.8.1\u002Finc\u002Ffunctions\u002Ffunctions-ajax.php\t2026-05-15 21:04:06.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-coupon-usage\u002F7.8.2\u002Finc\u002Ffunctions\u002Ffunctions-ajax.php\t2026-06-02 13:59:16.000000000 +0000\n@@ -3,10 +3,50 @@\n if ( !defined( 'ABSPATH' ) ) {\n     exit;\n }\n+if ( !function_exists( 'wcusage_ajax_coupon_code_matches_postid' ) ) {\n+    function wcusage_ajax_coupon_code_matches_postid(  $postid, $couponcode  ) {\n+        $postid = absint( $postid );\n+        $couponcode = sanitize_text_field( $couponcode );\n+        if ( !$postid || !$couponcode || !function_exists( 'wc_get_coupon_id_by_code' ) ) {\n+            return false;\n+        }\n+        return absint( wc_get_coupon_id_by_code( $couponcode ) ) === $postid;\n+    }\n+\n+}\n+if ( !function_exists( 'wcusage_ajax_user_can_access_coupon' ) ) {\n+    function wcusage_ajax_user_can_access_coupon(  $resolved_postid, $requested_postid = 0, $requested_code = ''  ) {\n+        $resolved_postid = absint( $resolved_postid );\n+        $requested_postid = absint( $requested_postid );\n+        $requested_code = sanitize_text_field( $requested_code );\n+        if ( !$resolved_postid ) {\n+            return false;\n+        }\n+        if ( wcusage_check_admin_access() ) {\n+            return true;\n+        }\n+        $coupon_user_id = absint( get_post_meta( $resolved_postid, 'wcu_select_coupon_user', true ) );\n+        $currentuserid = get_current_user_id();\n+        if ( $coupon_user_id && $currentuserid && $coupon_user_id === $currentuserid ) {\n+            return true;\n+        }\n+        if ( $coupon_user_id && $currentuserid && function_exists( 'wcusage_network_check_sub_affiliate' ) && wcusage_network_check_sub_affiliate( $currentuserid, $coupon_user_id ) ) {\n+            return true;\n+        }\n+        $wcusage_urlprivate = wcusage_get_setting_value( 'wcusage_field_urlprivate', '1' );\n+        if ( !$coupon_user_id && !$wcusage_urlprivate && $requested_postid && $requested_postid === $resolved_postid && wcusage_ajax_coupon_code_matches_postid( $requested_postid, $requested_code ) ) {\n+            return true;\n+        }\n+        return false;\n+    }\n+\n+}\n if ( !function_exists( 'wcusage_ajax_resolve_coupon' ) ) {\n     function wcusage_ajax_resolve_coupon(  $postid, $couponcode  ) {\n-        $resolved_postid = absint( $postid );\n-        $resolved_code = sanitize_text_field( $couponcode );\n+        $requested_postid = absint( $postid );\n+        $resolved_postid = $requested_postid;\n+        $requested_code = sanitize_text_field( $couponcode );\n+        $resolved_code = '';\n         if ( $resolved_postid && get_post_type( $resolved_postid ) === 'shop_coupon' ) {\n             $status = get_post_status( $resolved_postid );\n             if ( $status === 'trash' || $status === false ) {\n@@ -15,16 +55,27 @@\n         } else {\n             $resolved_postid = 0;\n         }\n-        if ( !$resolved_postid && $resolved_code && function_exists( 'wc_get_coupon_id_by_code' ) ) {\n-            $resolved_postid = wc_get_coupon_id_by_code( $resolved_code );\n+        if ( !$resolved_postid && $requested_code && function_exists( 'wc_get_coupon_id_by_code' ) ) {\n+            $resolved_postid = wc_get_coupon_id_by_code( $requested_code );\n         }\n         if ( !$resolved_postid ) {\n             echo '\u003Cdiv class=\"wcusage-error\">' . esc_html__( 'Error: Coupon does not exist.', 'woo-coupon-usage' ) . '\u003C\u002Fdiv>';\n             return array(0, '');\n         }\n-        if ( !$resolved_code ) {\n-            $resolved_code = get_the_title( $resolved_postid );\n+        \u002F\u002F Admins bypass all access checks and can view any coupon's data.\n+        if ( wcusage_check_admin_access() ) {\n+            $resolved_code = sanitize_text_field( get_post_field( 'post_title', $resolved_postid, 'raw' ) );\n+            return array($resolved_postid, $resolved_code);\n+        }\n+        if ( $requested_postid && $requested_code && !wcusage_ajax_coupon_code_matches_postid( $requested_postid, $requested_code ) ) {\n+            echo '\u003Cdiv class=\"wcusage-error\">' . esc_html__( 'Error: Coupon details do not match.', 'woo-coupon-usage' ) . '\u003C\u002Fdiv>';\n+            return array(0, '');\n+        }\n+        if ( !wcusage_ajax_user_can_access_coupon( $resolved_postid, $requested_postid, $requested_code ) ) {\n+            echo '\u003Cdiv class=\"wcusage-error\">' . esc_html__( 'Error: You do not have permission to access this data.', 'woo-coupon-usage' ) . '\u003C\u002Fdiv>';\n+            return array(0, '');\n         }\n+        $resolved_code = sanitize_text_field( get_post_field( 'post_title', $resolved_postid, 'raw' ) );\n         return array($resolved_postid, $resolved_code);\n     }","The exploit targets the `wcusage_load_page_orders` and `wcusage_load_page_statistics` AJAX actions. \n\n1. Authenticate as any Subscriber. \n2. Retrieve the `wcusage_dashboard_ajax_nonce` (normally present on the user's affiliate dashboard or account page).\n3. Send a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the parameters `action=wcusage_load_page_orders`, the retrieved nonce, and a `postid` of a shop_coupon that belongs to another user.\n4. Because the vulnerable `wcusage_ajax_resolve_coupon` function only resolves the coupon ID without verifying ownership or capabilities, the server will return the full order table or statistical data for the specified coupon ID.","gemini-3-flash-preview","2026-06-26 01:48:53","2026-06-26 01:49:52",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","7.8.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoo-coupon-usage\u002Ftags\u002F7.8.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwoo-coupon-usage.7.8.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoo-coupon-usage\u002Ftags\u002F7.8.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwoo-coupon-usage.7.8.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoo-coupon-usage\u002Ftags"]