[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fwV93-meo80Np9T3dvCJTclJU9X4z-LtEZmF4qrjtdZY":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-39478","anti-malware-security-and-brute-force-firewall-authenticated-contributor-php-object-injection","Anti-Malware Security and Brute-Force Firewall \u003C= 4.23.87 - Authenticated (Contributor+) PHP Object Injection","The Anti-Malware Security and Brute-Force Firewall plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 4.23.87 via deserialization of untrusted input. This makes it possible for authenticated attackers, with contributor-level access and above, to inject a PHP Object. No known POP chain is present in the vulnerable software. If a POP chain is present via an additional plugin or theme installed on the target system, it could allow the attacker to delete arbitrary files, retrieve sensitive data, or execute code.","gotmls",null,"\u003C=4.23.87","4.23.88","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Deserialization of Untrusted Data","2026-04-20 00:00:00","2026-04-30 14:45:05",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fc708698f-a38a-4213-a022-817b380e64df?source=api-prod",11,[22,23,24],"index.php","readme.txt","safe-load\u002Ftrace.php","researched",false,3,"# Research Plan: CVE-2026-39478 Authenticated (Contributor+) PHP Object Injection\n\n## 1. Vulnerability Summary\nThe **Anti-Malware Security and Brute-Force Firewall** plugin (versions \u003C= 4.23.87) is vulnerable to **PHP Object Injection**. The vulnerability exists because the plugin passes user-supplied data (specifically via the `definitions` or `settings` parameters in AJAX\u002FAdmin requests) into the `unserialize()` function without proper validation or integrity checks. \n\nThe sink is likely located within a decoding function such as `GOTMLS_decode()` (referenced in `safe-load\u002Ftrace.php`) or directly in AJAX handlers like `GOTMLS_scan_action` or `GOTMLS_load_update`. While no specific POP chain is identified in the plugin itself, the vulnerability allows an attacker with **Contributor-level** access to leverage any POP chain available in other active plugins or the WordPress core.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php` or `\u002Fwp-admin\u002Fadmin.php` (if handled via `admin_init`).\n- **Action**: `GOTMLS_scan_action` or `GOTMLS_load_update` (inferred from `index.php` line 74).\n- **Vulnerable Parameter**: `definitions` (or `GOTMLS_definitions_array`).\n- **Payload Encoding**: Base64 encoded serialized PHP object.\n- **Preconditions**:\n    - Attacker must have a **Contributor** account.\n    - The plugin must be active.\n    - The `user_can` capability for the plugin must be accessible to the Contributor (defaults to `edit_posts` in many GOTMLS configurations).\n\n## 3. Code Flow\n1. **Entry Point**: A Contributor user triggers an AJAX action (e.g., `GOTMLS_scan_action`) or accesses the settings page with specific `$_POST` parameters.\n2. **Capability Check**: The plugin checks if the user has the capability defined in `$GLOBALS[\"GOTMLS\"][\"tmp\"][\"settings_array\"][\"user_can\"]`. If this is `edit_posts` (standard for Contributors), the request proceeds.\n3. **Data Retrieval**: The plugin reads the `definitions` parameter from the `$_POST` or `$_REQUEST` superglobals.\n4. **Decoding**: The input is passed through `base64_decode()` and then into a decoding function. Verbatim from `safe-load\u002Ftrace.php` line 125, we see:\n   `$GLOBALS[\"GOTMLS\"][\"tmp\"][\"custom_whitelist\"][...] = GOTMLS_decode($get_whitelist_row[\"post_title\"]);`\n5. **Sink**: The `GOTMLS_decode()` function (not fully shown in snippet but standard in this plugin) executes `unserialize()` on the result:\n   ```php\n   function GOTMLS_decode($TXT) {\n       return maybe_unserialize(base64_decode($TXT)); \u002F\u002F Sink\n   }\n   ```\n\n## 4. Nonce Acquisition Strategy\nThe plugin uses a custom nonce generation function `GOTMLS_set_nonce`. Based on `index.php` line 70, the nonce is generated using `__FUNCTION__ . \"100\"` as the action string when in the header.\n\n### Strategy:\n1. **Target Page**: The Anti-Malware settings page: `\u002Fwp-admin\u002Fadmin.php?page=gotmls-settings`.\n2. **Identification**: The plugin enqueues scripts that contain the nonce and AJAX URL. Look for the `GOTMLS_display_header` output.\n3. **Extraction**:\n    - Navigate to the settings page as a Contributor.\n    - Use `browser_eval` to extract the nonce from the localized JavaScript objects.\n    - The variable name is likely `GOTMLS_js_object` or data localized via `wp_localize_script`.\n\n**Verification of Action String**: \nCheck `index.php` line 74: `GOTMLS_admin_url('GOTMLS_load_update', $head_nonce.'&UPDATE_definitio...')`. \nThis confirms that the nonce associated with `GOTMLS_load_update` is required.\n\n## 5. Exploitation Strategy\n\n### Step 1: Preparation\nCreate a Contributor user to simulate the attacker.\n```bash\nwp user create attacker attacker@example.com --role=contributor --user_pass=password\n```\n\n### Step 2: Nonce Extraction\nNavigate to the plugin dashboard and extract the nonce.\n- **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin.php?page=gotmls-settings`\n- **JS Variable to check**: `window.GOTMLS_js_object?.nonce` or look for the `head_nonce` in the HTML source.\n\n### Step 3: Payload Construction\nConstruct a serialized object. Since no POP chain is provided, we use a simple `stdClass` to verify the `unserialize` call (can be tracked in logs if `WP_DEBUG` is on).\n```php\n# Serialized payload: O:8:\"stdClass\":0:{}\n# Base64: Tz04OiJzdGRDbGFzcyI6MDp7fQ==\n```\n\n### Step 4: Execute HTTP Request\nSend the payload via `admin-ajax.php`.\n\n- **Method**: POST\n- **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body**:\n  ```text\n  action=GOTMLS_scan_action&nonce=[EXTRACTED_NONCE]&definitions=Tz04OiJzdGRDbGFzcyI6MDp7fQ==\n  ```\n\n## 6. Test Data Setup\n1. **Ensure Plugin is Configured**: The plugin might require \"Definition Updates\" to be clicked once to initialize the `settings_array`.\n2. **Access Control**: Verify that a Contributor can see the menu:\n   ```bash\n   wp eval 'echo get_option(\"GOTMLS_settings_array\")[\"user_can\"];'\n   ```\n   If it is not `edit_posts`, the PoC may need to escalate to a role that matches the requirement.\n\n## 7. Expected Results\n- **Success**: The server processes the request. If a logging\u002Fmonitoring tool is attached (like `Xdebug` or custom error logging in `unserialize`), it will show the `stdClass` object being instantiated.\n- **Response**: The AJAX handler usually returns a JSON response or an encoded string containing \"Success\" or scan progress indicators.\n\n## 8. Verification Steps\nAfter the HTTP request:\n1. **Check Logs**: Monitor `wp-content\u002Fdebug.log` for any \"unserialization\" errors or notices.\n2. **Database State**: Some objects might alter options. Check if `GOTMLS_definitions_array` was modified:\n   ```bash\n   wp option get GOTMLS_definitions_array\n   ```\n\n## 9. Alternative Approaches\nIf `GOTMLS_scan_action` fails:\n- **Target `GOTMLS_load_update`**: This is a direct admin action. Use `GET` or `POST` to `\u002Fwp-admin\u002Fadmin.php?page=GOTMLS_load_update&definitions=[PAYLOAD]&_wpnonce=[NONCE]`.\n- **Target `GOTMLS_View_Quarantine`**: As seen in `index.php` line 52, if a Contributor can view quarantine, they may be able to trigger the `GOTMLS_decode` sink by visiting that page if the database contains a malicious quarantine entry. This would be a two-step \"Stored Object Injection\" attack.","The Anti-Malware Security and Brute-Force Firewall plugin is vulnerable to PHP Object Injection via the deserialization of user-supplied data in the GOTMLS_decode and GOTMLS_uckserialize functions. Authenticated attackers with Contributor-level access can exploit this by submitting crafted base64-encoded serialized objects through parameters like 'definitions' in various AJAX and admin actions.","\u002F\u002F safe-load\u002Ftrace.php line 196\nfunction GOTMLS_uckserialize($unsafe_serialized) {\n\tif (!(is_array($unsafe_serialized)) && (is_array($safe_unserialized = @unserialize(preg_replace('\u002F[oc]:\\d+:\".*?\":(\\d+):\\{\u002Fis', 'a:\\1:{', $unsafe_serialized)))))\n\t\treturn $safe_unserialized;\n\treturn $unsafe_serialized;\n}\n\n---\n\n\u002F\u002F safe-load\u002Ftrace.php line 125 (inside GOTMLS_load_contents)\nforeach ($get_whitelist_rows as $get_whitelist_row)\n    $GLOBALS[\"GOTMLS\"][\"tmp\"][\"custom_whitelist\"][$get_whitelist_row[\"chksum\"]] = GOTMLS_decode($get_whitelist_row[\"post_title\"]);","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.87\u002Findex.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.88\u002Findex.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.87\u002Findex.php\t2026-02-26 18:15:34.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.88\u002Findex.php\t2026-03-09 14:48:00.000000000 +0000\n@@ -10,7 +10,7 @@\n Description: This Anti-Virus\u002FAnti-Malware plugin searches for Malware and other Virus like threats and vulnerabilities on your server and helps you remove them. It's always growing and changing to adapt to new threats so let me know if it's not working for you.\n License: GPLv3 or later\n License URI: https:\u002F\u002Fwww.gnu.org\u002Flicenses\u002Fgpl-3.0.html#license-text\n-Version: 4.23.87\n+Version: 4.23.88\n Requires PHP: 5.6\n Requires CP: 1.1.1\n *\u002F\n@@ -633,6 +633,7 @@\n \t$saved = false;\n \t$moreJS = \"\";\n \t$finJS = \"\\n}\";\n+\t$user_donations_src = 0;\n \t$form = 'registerKeyForm';\n \t$innerHTML = \"\u003Cli style=\\\\\\\"color: #f00\\\\\\\">Your Installation Key could not be confirmed!\u003C\u002Fli>\";\n \t$autoUpJS = '\u003Cspan style=\"color: #C00;\">This new feature is currently only available to registered users who have donated $29 or more.\u003C\u002Fspan>\u003Cbr \u002F>';\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.87\u002Freadme.txt \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.88\u002Freadme.txt\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.87\u002Freadme.txt\t2026-02-26 18:15:34.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.88\u002Freadme.txt\t2026-03-09 14:48:00.000000000 +0000\n@@ -7,8 +7,8 @@\n Tags: anti-malware, security, scanner, brute-force, firewall\n License: GPLv3 or later\n License URI: https:\u002F\u002Fwww.gnu.org\u002Flicenses\u002Fgpl-3.0.html#license-text\n-Version: 4.23.87\n-Stable tag: 4.23.87\n+Version: 4.23.88\n+Stable tag: 4.23.88\n Requires at least: 3.3\n Tested up to: 6.9.1\n \n@@ -100,6 +100,9 @@\n \n == Changelog ==\n \n+= 4.23.88 =\n+* Fixed PHP Object Injection vulnerability with DB Scan.\n+\n = 4.23.87 =\n * Checked code for compatibility with WordPress 6.9.1 and ClassicPress 2.6.\n \n@@ -521,6 +524,9 @@\n \n == Upgrade Notice ==\n \n+= 4.23.88 =\n+Fixed PHP Object Injection vulnerability with DB Scan.\n+\n = 4.23.87 =\n Checked code for compatibility with WordPress 6.9.1 and ClassicPress 2.6.\n \n diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.87\u002Fsafe-load\u002Ftrace.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.88\u002Fsafe-load\u002Ftrace.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.87\u002Fsafe-load\u002Ftrace.php\t2026-02-26 18:15:34.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgotmls\u002F4.23.88\u002Fsafe-load\u002Ftrace.php\t2026-03-09 14:48:00.000000000 +0000\n@@ -4,7 +4,7 @@\n  * @package GOTMLS\n *\u002F\n \n-define(\"GOTMLS_Version\", '4.23.87');\n+define(\"GOTMLS_Version\", '4.23.88');\n define(\"GOTMLS_SAFELOAD_DIR\", dirname(__FILE__).\"\u002F\");\n define(\"GOTMLS_CHMOD_FILE\", 0644);\n define(\"GOTMLS_CHMOD_DIR\", 0755);\n@@ -194,7 +194,7 @@\n }\n \n function GOTMLS_uckserialize($unsafe_serialized) {\n-\tif (!(is_array($unsafe_serialized)) && (is_array($safe_unserialized = @unserialize(preg_replace('\u002F[oc]:\\d+:\".*?\":(\\d+):\\{\u002Fis', 'a:\\1:{', $unsafe_serialized)))))\n+\tif (!(is_array($unsafe_serialized)) && (is_array($safe_unserialized = @unserialize(preg_replace('\u002F[oc]:[\\+\\d]++:\".*?\":([\\+\\d]++):\\{\u002Fis', 'a:\\1:{', $unsafe_serialized)))))\n \t\treturn $safe_unserialized;\n \treturn $unsafe_serialized;\n }","To exploit this vulnerability, an attacker with Contributor-level access must first obtain a valid nonce from the plugin's admin dashboard (typically via the 'head_nonce' in the HTML or GOTMLS_js_object). The attacker then sends a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the action 'GOTMLS_scan_action' (or 'GOTMLS_load_update' on the settings page). The payload is a base64-encoded PHP serialized object provided in the 'definitions' parameter. The plugin's GOTMLS_uckserialize function attempts to sanitize the serialized string by replacing object tags ('O:' or 'C:') with array tags ('a:') using a regex. However, this regex can be bypassed (e.g., using a '+' sign in the length quantifier), causing the original object to be deserialized by unserialize(), triggering a POP chain if one exists in the environment.","gemini-3-flash-preview","2026-05-04 19:34:02","2026-05-04 19:34:47",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","4.23.87","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgotmls\u002Ftags\u002F4.23.87","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgotmls.4.23.87.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgotmls\u002Ftags\u002F4.23.88","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgotmls.4.23.88.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgotmls\u002Ftags"]