[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f3i3FvtgpBIPFR6VIMNXCuVA0pLEfL_FcnnGDbU_TAMA":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":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-32331","textmetrics-missing-authorization-2","Textmetrics \u003C= 3.6.4 - Missing Authorization","The Textmetrics plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.6.4. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.","webtexttool",null,"\u003C=3.6.4","3.6.5","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-02-08 00:00:00","2026-04-15 20:45:07",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8fe7b884-c245-4412-b43d-38d0565fccbd?source=api-prod",67,[22,23,24],"README.txt","core\u002Fclass-webtexttool-core.php","webtexttool.php","researched",false,3,"# Research Plan: CVE-2026-32331 Textmetrics Missing Authorization\n\n## 1. Vulnerability Summary\nThe Textmetrics plugin for WordPress (versions \u003C= 3.6.4) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, an AJAX callback function (likely `wtt_ajax_save_meta` or `wtt_save_social_meta`) fails to perform a capability check (e.g., `current_user_can('edit_post', $post_id)`). This allows an authenticated attacker with Subscriber-level permissions to modify the SEO and social metadata of arbitrary posts or pages by sending crafted AJAX requests to `admin-ajax.php`.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `wtt_ajax_save_meta` (inferred from plugin history and source patterns)\n- **Method:** `POST`\n- **Authentication:** Required (Subscriber-level access)\n- **Payload Parameter:** `post_id` (the target post), `wttcontent` (the nonce), and metadata fields like `wtt_social_title` or `wtt_social_description`.\n- **Precondition:** The attacker must obtain a valid nonce for the `wttcallback` action. While Subscribers don't normally edit posts, the nonce is generated in the `wtt_social_meta_box` function and may be exposed through other authenticated views or shared nonce actions.\n\n","The Textmetrics plugin for WordPress is vulnerable to unauthorized post metadata modification due to insufficient capability checks in its AJAX handling logic. Authenticated attackers with subscriber-level permissions or higher can exploit this to alter SEO and social metadata for arbitrary posts or pages.","\u002F\u002F core\u002Fclass-webtexttool-core.php\n\n\u002F* Line 735 in version 3.6.4 *\u002F\n$output = array(\"message\" => 'process server ajax failed'); \u002F\u002F set default output message\n$action = $this->get_webtexttoolnonce_action(); \u002F\u002F text used to generate or check the nonce.\n\nif (!current_user_can('edit_posts')) {\n    exit;\n}\n\n\u002F\u002F check if the nonce and data exist, otherwise exit\nif (array_key_exists('nonce', $_POST) && array_key_exists('data', $_POST) && array_key_exists('postId', $_POST)) {\n    $nonce = htmlentities($_POST['nonce']);\n    if (wp_verify_nonce($nonce, $action)) {\n        $data = $_POST['data'];\n        $pageid = $_POST['postId'];\n\n        $option_key = $data['option'];\n        $option_value = $data['value'];","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwebtexttool\u002F3.6.4\u002Fcore\u002Fclass-webtexttool-core.php\t2026-02-05 11:03:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwebtexttool\u002F3.6.5\u002Fcore\u002Fclass-webtexttool-core.php\t2026-02-26 10:44:50.000000000 +0000\n@@ -735,10 +735,6 @@\n         $output = array(\"message\" => 'process server ajax failed'); \u002F\u002F set default output message\n         $action = $this->get_webtexttoolnonce_action(); \u002F\u002F text used to generate or check the nonce.\n \n-        if (!current_user_can('edit_posts')) {\n-            exit;\n-        }\n-\n         \u002F\u002F check if the nonce and data exist, otherwise exit\n         if (array_key_exists('nonce', $_POST) && array_key_exists('data', $_POST) && array_key_exists('postId', $_POST)) {\n             $nonce = htmlentities($_POST['nonce']);\n@@ -746,6 +742,14 @@\n                 $data = $_POST['data'];\n                 $pageid = $_POST['postId'];\n \n+                \u002F\u002F Check if user can edit this specific post\n+                if (!current_user_can('edit_post', $pageid)) {\n+                    $output['message'] = 'unauthorized';\n+                    header(\"Content-Type: application\u002Fjson\");\n+                    echo json_encode($output);\n+                    die();\n+                }\n+\n                 $option_key = $data['option'];\n                 $option_value = $data['value'];","To exploit this vulnerability, an authenticated attacker with Subscriber-level access (or higher) must first obtain a valid WordPress nonce for the 'wttcallback' action. The attacker then sends a POST request to the `\u002Fwp-admin\u002Fadmin-ajax.php` endpoint with the 'action' parameter set to the plugin's meta-saving function. The payload must include the 'postId' of the target post to be modified, the 'nonce', and a 'data' array containing the 'option' (meta key) and 'value' (new content) they wish to update. Because the plugin lacks a resource-specific capability check (like `current_user_can('edit_post', $postId)`), the server will process the metadata update for any post ID provided, regardless of whether the attacker has permission to edit that specific content.","gemini-3-flash-preview","2026-04-21 03:11:04","2026-04-21 03:11:57",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","3.6.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebtexttool\u002Ftags\u002F3.6.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwebtexttool.3.6.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebtexttool\u002Ftags\u002F3.6.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwebtexttool.3.6.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebtexttool\u002Ftags"]