[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fgN1TE-3Dj033k9APK6pAfFZ76YZRMaLI41WOVhcYK9Q":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-57418","sprout-invoices-client-invoicing-estimates-missing-authorization","Sprout Invoices – Client Invoicing & Estimates \u003C= 20.8.13 - Missing Authorization","The Sprout Invoices – Client Invoicing & Estimates plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 20.8.13. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.","sprout-invoices",null,"\u003C=20.8.13","20.8.14","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-07-08 00:00:00","2026-07-14 19:39:42",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff0292877-33ca-425f-a95b-547b3bed2c10?source=api-prod",7,[22,23,24,25,26,27,28,29],"Sprout_Invoices.class.php","bundles\u002FAddons.php","controllers\u002Fadmin\u002FSettings_API.php","controllers\u002Festimates\u002FEstimates.php","controllers\u002Finvoices\u002FInvoices.php","readme.txt","resources\u002Fadmin\u002Fjs\u002Fest_and_invoices.js","resources\u002Fadmin\u002Fjs\u002Fsettings.js","researched",false,3,"# Exploitation Research Plan: CVE-2026-57418 (Missing Authorization)\n\n## 1. Vulnerability Summary\nThe **Sprout Invoices – Client Invoicing & Estimates** plugin (version \u003C= 20.8.13) is vulnerable to missing authorization in several AJAX handlers. Specifically, functions registered under the `wp_ajax_` prefix in `SI_Settings_API` and `SI_Estimates`\u002F`SI_Invoices` fail to verify the user's capability (authorization) before performing actions. This allows an authenticated user with Subscriber-level access to perform unauthorized actions, such as modifying plugin settings or sending arbitrary notifications.\n\n## 2. Attack Vector Analysis\n- **Target Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Vulnerable Action:** `si_gtag_option_action` (and potentially `si_stripe_option_action` or `sa_send_est_notification`).\n- **Required Authentication:** Subscriber or higher.\n- **Payload Parameter:** `option` (for `si_gtag_option_action`) or `sa_metabox_recipients` (for notification spam).\n- **Security Check:** The functions verify a nonce (usually passed as `security` or `nonce`) but do not check for the `manage_sprout_invoices_options` or `edit_sprout_invoices` capabilities.\n\n## 3. Code Flow\n1. **Registration:** In `controllers\u002Fadmin\u002FSettings_API.php`,","The Sprout Invoices plugin for WordPress is vulnerable to unauthorized access because multiple AJAX and REST API handlers fail to perform capability checks. Authenticated users, including those with subscriber-level permissions, can perform unauthorized actions such as sending arbitrary notifications for invoices and estimates or managing plugin add-ons.","\u002F\u002F controllers\u002Festimates\u002FEstimates.php:127\n\tpublic static function maybe_send_notification() {\n\t\t\u002F\u002F ...\n\t\tif ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['sa_send_metabox_notification_nonce'] ) ), SI_Controller::NONCE ) ) {\n\t\t\tself::ajax_fail( 'Not going to fall for it!' ); }\n\n\t\tif ( ! isset( $_REQUEST['sa_send_metabox_doc_id'] ) ) {\n\t\t\tself::ajax_fail( 'Forget something (id)?' ); }\n\n\t\tif ( get_post_type( sanitize_text_field( wp_unslash( $_REQUEST['sa_send_metabox_doc_id'] ) ) ) !== SI_Estimate::POST_TYPE ) {\n\t\t\treturn;\n\t\t}\n\n\t\t$recipients = ( isset( $_REQUEST['sa_metabox_recipients'] ) )\n\t\t\t? array_map( 'sanitize_text_field', ( wp_unslash( $_REQUEST['sa_metabox_recipients'] ) ) )\n\t\t\t: array();\n\n---\n\n\u002F\u002F controllers\u002Finvoices\u002FInvoices.php:115\n\tpublic static function maybe_send_notification() {\n\t\t\u002F\u002F ...\n\t\tif ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['sa_send_metabox_notification_nonce'] ) ), SI_Controller::NONCE ) ) {\n\t\t\tself::ajax_fail( 'Not going to fall for it!' );\n\t\t}\n\n\t\tif ( ! isset( $_REQUEST['sa_send_metabox_doc_id'] ) ) {\n\t\t\tself::ajax_fail( 'Forget something (id)?' );\n\t\t}\n\n\t\tif ( get_post_type( sanitize_text_field( wp_unslash( $_REQUEST['sa_send_metabox_doc_id'] ) ) ) !== SI_Invoice::POST_TYPE ) {\n\t\t\treturn;\n\t\t}\n\n\t\t$recipients = ( isset( $_REQUEST['sa_metabox_recipients'] ) ) ? array_map( 'sanitize_text_field', ( wp_unslash( $_REQUEST['sa_metabox_recipients'] ) ) ) : array();\n\n---\n\n\u002F\u002F controllers\u002Fadmin\u002FSettings_API.php:673\n\t\t\t\t'callback' => function () {\n\t\t\t\t\t\u002F\u002F phpcs:disable WordPress.Security.NonceVerification.Missing -- WordPress REST API validates authentication via X-WP-Nonce header; permission_callback enforces capability\n\t\t\t\t\t$_POST = stripslashes_deep( $_POST );\n\n\t\t\t\t\tif ( isset( $_POST['activate'] ) ) {\n\t\t\t\t\t\tSA_Addons::activate_addon( sanitize_text_field( wp_unslash( $_POST['activate'] ) ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( isset( $_POST['deactivate'] ) ) {\n\t\t\t\t\t\tSA_Addons::deactivate_addon( sanitize_text_field( wp_unslash( $_POST['deactivate'] ) ) );\n\n\t\t\t\t\t}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.13\u002Fcontrollers\u002Festimates\u002FEstimates.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.14\u002Fcontrollers\u002Festimates\u002FEstimates.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.13\u002Fcontrollers\u002Festimates\u002FEstimates.php\t2026-04-30 17:43:24.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.14\u002Fcontrollers\u002Festimates\u002FEstimates.php\t2026-06-04 15:16:58.000000000 +0000\n@@ -141,10 +141,33 @@\n \t\tif ( ! isset( $_REQUEST['sa_send_metabox_doc_id'] ) ) {\n \t\t\tself::ajax_fail( 'Forget something (id)?' ); }\n \n-\t\tif ( get_post_type( sanitize_text_field( wp_unslash( $_REQUEST['sa_send_metabox_doc_id'] ) ) ) !== SI_Estimate::POST_TYPE ) {\n+\t\t$doc_id    = absint( wp_unslash( $_REQUEST['sa_send_metabox_doc_id'] ) );\n+\t\t$post_type = get_post_type( $doc_id );\n+\n+\t\tif ( SI_Invoice::POST_TYPE === $post_type ) {\n \t\t\treturn;\n \t\t}\n \n+\t\tif ( SI_Estimate::POST_TYPE !== $post_type ) {\n+\t\t\tself::ajax_fail( 'Not an invoice or estimate.' );\n+\t\t}\n+\n+\t\tif ( ! current_user_can( 'edit_post', $doc_id ) ) {\n+\t\t\tself::ajax_fail( 'You do not have permission to send this notification.' );\n+\t\t}\n+\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.13\u002Fcontrollers\u002Finvoices\u002FInvoices.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.14\u002Fcontrollers\u002Finvoices\u002FInvoices.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.13\u002Fcontrollers\u002Finvoices\u002FInvoices.php\t2026-04-30 17:43:24.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsprout-invoices\u002F20.8.14\u002Fcontrollers\u002Finvoices\u002FInvoices.php\t2026-06-04 15:16:58.000000000 +0000\n@@ -125,10 +125,33 @@\n \t\t\tself::ajax_fail( 'Forget something (id)?' );\n \t\t}\n \n-\t\tif ( get_post_type( sanitize_text_field( wp_unslash( $_REQUEST['sa_send_metabox_doc_id'] ) ) ) !== SI_Invoice::POST_TYPE ) {\n+\t\t$doc_id    = absint( wp_unslash( $_REQUEST['sa_send_metabox_doc_id'] ) );\n+\t\t$post_type = get_post_type( $doc_id );\n+\n+\t\tif ( SI_Estimate::POST_TYPE === $post_type ) {\n \t\t\treturn;\n \t\t}\n \n+\t\tif ( SI_Invoice::POST_TYPE !== $post_type ) {\n+\t\t\tself::ajax_fail( 'Not an invoice or estimate.' );\n+\t\t}\n+\n+\t\tif ( ! current_user_can( 'edit_post', $doc_id ) ) {\n+\t\t\tself::ajax_fail( 'You do not have permission to send this notification.' );\n+\t\t}","To exploit this vulnerability, an attacker first authenticates with a low-privileged account (such as a Subscriber). They then extract the global nonce from the frontend via the `si_js_object.security` variable, which is exposed to all logged-in users. Using this nonce, the attacker can make POST requests to `\u002Fwp-admin\u002Fadmin-ajax.php` with the action `sa_send_est_notification`. By providing an arbitrary invoice or estimate ID in the `sa_send_metabox_doc_id` parameter and a list of target emails in `sa_metabox_recipients[]`, the attacker can trigger the plugin to send official invoice\u002Festimate notifications to any address, potentially leading to information disclosure or spam.","gemini-3-flash-preview","2026-07-25 08:12:34","2026-07-25 08:14:10",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","20.8.13","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsprout-invoices\u002Ftags\u002F20.8.13","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsprout-invoices.20.8.13.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsprout-invoices\u002Ftags\u002F20.8.14","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsprout-invoices.20.8.14.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsprout-invoices\u002Ftags"]