[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fZP-WRud81TvVs2uHwc04LYwEMjMDQUh9ioD4wbkTsH4":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":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":33,"research_vulnerable_code":34,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"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":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":40},"CVE-2026-32541","premmerce-redirect-manager-missing-authorization","Premmerce Redirect Manager \u003C= 1.0.12 - Missing Authorization","The Premmerce Redirect Manager plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.0.12. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.","premmerce-redirect-manager",null,"\u003C=1.0.12","1.0.13","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-03-20 00:00:00","2026-03-27 19:24:58",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F56a68cad-2abf-4b22-ae05-243e8901a9d8?source=api-prod",8,[22,23,24,25,26,27,28],"assets\u002Fadmin\u002Fjs\u002Fpremmerce-redirect.js","premmerce-redirect.php","readme.txt","src\u002FAdmin\u002FAdmin.php","src\u002FAdmin\u002FRedirectsTable.php","src\u002FRedirectModel.php","src\u002FRedirectPlugin.php","researched",false,3,"# Vulnerability Research Plan: CVE-2026-32541 Premmerce Redirect Manager \u003C= 1.0.12\n\n## 1. Vulnerability Summary\nThe **Premmerce Redirect Manager** plugin (up to version 1.0.12) contains a missing authorization vulnerability. While the plugin restricts access to its main administrative interface to users with the `manage_options` capability, it registers several `admin_post` and `wp_ajax` hooks that fail to perform secondary capability checks within their handler functions. This allows authenticated users with low-level privileges (like **Subscribers**) to perform actions intended for administrators, specifically deleting redirects.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-post.php` (for deletions) or `\u002Fwp-admin\u002Fadmin-ajax.php` (for information leakage).\n- **Primary Action:** `premmerce_delete_redirect` (registered via `admin_post` hook).\n- **Secondary Action:** `get_posts_by_string` (registered via `wp_ajax` hook).\n- **Parameters:**\n  - `action`: `premmerce_delete_redirect`\n  - `id`: The integer ID of the redirect to be deleted.\n  - `_wpnonce`: (Potentially required) CSRF token.\n- **Authentication Level:** Authenticated (Subscriber and above).\n- **Preconditions:** At least one redirect must exist in the `wp_premmerce_redirects` table.\n\n## 3","The Premmerce Redirect Manager plugin for WordPress is vulnerable to unauthorized access and information disclosure due to missing capability checks and nonce verification on several AJAX and admin-post endpoints. Authenticated attackers, including those with Subscriber-level permissions, can leak the titles of private or password-protected posts and terms, or potentially delete configured redirects.","\u002F\u002F src\u002FAdmin\u002FAdmin.php @ line 125\npublic function getPostsByString()\n{\n    if (isset($_POST['type'])) {\n        $objects = $this->model->getPostsByString($_POST);\n\n        wp_send_json($objects);\n    }\n}\n\n---\n\n\u002F\u002F src\u002FRedirectModel.php @ line 166\npublic function getPostsByString($data)\n{\n    if (in_array($data['type'], array('product', 'post', 'page'))) {\n        $objects = (new \\WP_Query(array(\n            's'           => isset($data['s'])? $data['s'] : '',\n            'post_type'   => $data['type'],\n            'numberposts' => 10,\n        )))->posts;\n    } else {\n        $objects = get_terms(array(\n            'hide_empty' => false,\n            'search'     => isset($data['s'])? $data['s'] : '',\n            'taxonomy'   => $data['type'],\n        ));\n    }\n\n    return $objects;\n}\n\n---\n\n\u002F\u002F src\u002FAdmin\u002FAdmin.php @ line 116\nadd_action('admin_post_premmerce_delete_redirect', array($this, 'deleteRedirect'));\nadd_action('wp_ajax_get_posts_by_string', array($this, 'getPostsByString'));","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.12\u002Fassets\u002Fadmin\u002Fjs\u002Fpremmerce-redirect.js \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.13\u002Fassets\u002Fadmin\u002Fjs\u002Fpremmerce-redirect.js\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.12\u002Fassets\u002Fadmin\u002Fjs\u002Fpremmerce-redirect.js\t2018-01-11 08:14:08.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.13\u002Fassets\u002Fadmin\u002Fjs\u002Fpremmerce-redirect.js\t2026-02-18 21:55:06.000000000 +0000\n@@ -13,6 +13,7 @@\n                         s: params.term,\n                         type: 'product',\n                         action: 'get_posts_by_string',\n+                        _wpnonce: premmerceRedirect.nonce,\n                     }\n                 },\n                 processResults: function(data) {\n@@ -39,6 +40,7 @@\n                         s: params.term,\n                         type: 'product_cat',\n                         action: 'get_posts_by_string',\n+                        _wpnonce: premmerceRedirect.nonce,\n                     }\n                 },\n                 processResults: function(data) {\n@@ -65,6 +67,7 @@\n                         s: params.term,\n                         type: 'category',\n                         action: 'get_posts_by_string',\n+                        _wpnonce: premmerceRedirect.nonce,\n                     }\n                 },\n                 processResults: function(data) {\n@@ -91,6 +94,7 @@\n                         s: params.term,\n                         type: 'post',\n                         action: 'get_posts_by_string',\n+                        _wpnonce: premmerceRedirect.nonce,\n                     }\n                 },\n                 processResults: function(data) {\n@@ -117,6 +121,7 @@\n                         s: params.term,\n                         type: 'page',\n                         action: 'get_posts_by_string',\n+                        _wpnonce: premmerceRedirect.nonce,\n                     }\n                 },\n                 processResults: function(data) {\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.12\u002Fsrc\u002FAdmin\u002FAdmin.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.13\u002Fsrc\u002FAdmin\u002FAdmin.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.12\u002Fsrc\u002FAdmin\u002FAdmin.php\t2023-08-23 11:19:54.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.13\u002Fsrc\u002FAdmin\u002FAdmin.php\t2026-02-18 21:55:06.000000000 +0000\n@@ -248,8 +248,20 @@\n      *\u002F\n     public function getPostsByString()\n     {\n+        if (! current_user_can('manage_options')) {\n+            wp_send_json_error(array( 'message' => __('You do not have permission to perform this action.', 'premmerce-redirect') ), 403);\n+        }\n+\n+        if (! isset($_POST['_wpnonce']) || ! wp_verify_nonce(wp_unslash($_POST['_wpnonce']), 'premmerce_redirect_search')) {\n+            wp_send_json_error(array( 'message' => __('Security check failed.', 'premmerce-redirect') ), 403);\n+        }\n+\n         if (isset($_POST['type'])) {\n-            $objects = $this->model->getPostsByString($_POST);\n+            $data = array(\n+                'type' => sanitize_text_field($_POST['type']),\n+                's'    => isset($_POST['s']) ? sanitize_text_field($_POST['s']) : '',\n+            );\n+            $objects = $this->model->getPostsByString($data);\n \n             wp_send_json($objects);\n         }\n@@ -327,6 +339,9 @@\n     {\n         wp_enqueue_script('select2', $this->fileManager->locateAsset('admin\u002Fjs\u002Fselect2.min.js'));\n         wp_enqueue_script('premmerce-redirect', $this->fileManager->locateAsset('admin\u002Fjs\u002Fpremmerce-redirect.js'));\n+        wp_localize_script('premmerce-redirect', 'premmerceRedirect', array(\n+            'nonce' => wp_create_nonce('premmerce_redirect_search'),\n+        ));\n         wp_enqueue_style('select2', $this->fileManager->locateAsset('admin\u002Fcss\u002Fselect2.min.css'));\n         wp_enqueue_style('premmerce-redirect', $this->fileManager->locateAsset('admin\u002Fcss\u002Fpremmerce-redirect.css'));\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.12\u002Fsrc\u002FRedirectModel.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.13\u002Fsrc\u002FRedirectModel.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.12\u002Fsrc\u002FRedirectModel.php\t2018-08-21 13:20:46.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpremmerce-redirect-manager\u002F1.0.13\u002Fsrc\u002FRedirectModel.php\t2026-02-18 21:55:06.000000000 +0000\n@@ -166,18 +166,25 @@\n      *\u002F\n     public function getPostsByString($data)\n     {\n-        if (in_array($data['type'], array('product', 'post', 'page'))) {\n+        $allowed_post_types = array( 'product', 'post', 'page' );\n+        $allowed_taxonomies = array( 'product_cat', 'category' );\n+\n+        if (in_array($data['type'], $allowed_post_types, true)) {\n             $objects = (new \\WP_Query(array(\n-                's'           => isset($data['s'])? $data['s'] : '',\n-                'post_type'   => $data['type'],\n-                'numberposts' => 10,\n+                's'              => isset($data['s']) ? $data['s'] : '',\n+                'post_type'      => $data['type'],\n+                'posts_per_page' => 10,\n+                'has_password'   => false,\n+                'post_status'    => 'publish',\n             )))->posts;\n-        } else {\n+        } elseif (in_array($data['type'], $allowed_taxonomies, true)) {\n             $objects = get_terms(array(\n                 'hide_empty' => false,\n-                'search'     => isset($data['s'])? $data['s'] : '',\n+                'search'     => isset($data['s']) ? $data['s'] : '',\n                 'taxonomy'   => $data['type'],\n             ));\n+        } else {\n+            $objects = array();\n         }\n \n         return $objects;","The exploit targets the AJAX endpoint `get_posts_by_string` which is available to all authenticated users. \n\n1. Authentication: Log in as a low-privileged user (Subscriber).\n2. Request: Send a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php`.\n3. Parameters: \n   - Set `action` to `get_posts_by_string`.\n   - Set `type` to a sensitive post type like `post`, `page`, or `product`.\n   - Set `s` to a search term (empty or specific string).\n4. Outcome: The server returns a JSON array of objects containing the IDs and titles of the matching posts. Because the vulnerable version lacks query constraints, this includes titles of posts with statuses like 'draft', 'pending', or 'private', as well as password-protected posts.","gemini-3-flash-preview","2026-04-18 02:08:42","2026-04-18 02:09:41",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","1.0.12","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpremmerce-redirect-manager\u002Ftags\u002F1.0.12","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpremmerce-redirect-manager.1.0.12.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpremmerce-redirect-manager\u002Ftags\u002F1.0.13","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpremmerce-redirect-manager.1.0.13.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpremmerce-redirect-manager\u002Ftags"]