[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fRNLrOxRvAVba6wQO3QnpXpBwYt9vVi-RJ_dbR0XWz_o":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-2354","swiss-toolkit-for-wp-authenticated-author-arbitrary-file-upload-via-uploadextensionfiles","Swiss Toolkit For WP \u003C= 1.4.6 - Authenticated (Author+) Arbitrary File Upload via upload_extension_files()","The Swiss Toolkit For WP plugin for WordPress is vulnerable to arbitrary file upload due to a flawed file type validation bypass in the `upload_extension_files()` function in all versions up to, and including, 1.4.6. The `upload_extension_files()` function hooks into WordPress's `wp_check_filetype_and_ext` filter and uses `strpos()` to check if a filename contains a configured extension string, rather than verifying the actual file extension. This makes it possible for authenticated attackers, with Author-level access and above, to upload arbitrary files (including PHP) on the affected site's server which may make remote code execution possible, granted the \"Enhanced Multi-Format Image Support\" feature is enabled with at least one extension (e.g., avif) in the allowed formats.","swiss-toolkit-for-wp",null,"\u003C=1.4.6","high",8.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Unrestricted Upload of File with Dangerous Type","2026-07-10 15:27:04","2026-07-11 03:44:21",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F06bccd2e-6891-433a-9f5b-3ec0c30afef4?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-2354 - Swiss Toolkit For WP Arbitrary File Upload\n\n## 1. Vulnerability Summary\nThe **Swiss Toolkit For WP** plugin (versions \u003C= 1.4.6) contains an arbitrary file upload vulnerability. The flaw exists in the `upload_extension_files()` function, which is hooked into the WordPress `wp_check_filetype_and_ext` filter. \n\nThe function attempts to allow additional image formats (like `.avif`) by checking if the filename contains an allowed extension string. However, it uses `strpos()` for this check instead of verifying that the file actually ends with the allowed extension or validating the MIME type correctly. This allows an authenticated user with Author-level permissions or higher to upload PHP files by including an allowed extension string anywhere in the filename (e.g., `malicious.avif.php`).\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `wp-admin\u002Fasync-upload.php` (Standard WordPress media upload handler).\n*   **Action:** `upload-attachment`.\n*   **Authentication:** Authenticated, Author level or higher (requires `upload_files` capability).\n*   **Precondition:** The feature \"Enhanced Multi-Format Image Support\" must be enabled in the Swiss Toolkit settings, and at least one extension (e.g., `avif`) must be added to the allowed formats list.\n*   **Payload Parameter:** `async-upload` (the file blob) and `_wpnonce`.\n\n## 3. Code Flow (Inferred)\n1.  **Entry Point:** An Author user uploads a file via the Media Library or a post editor.\n2.  **WordPress Core:** `wp_handle_upload()` calls `wp_check_filetype_and_ext()`.\n3.  **Plugin Hook:** The plugin's `upload_extension_files()` function intercepts the check via the `wp_check_filetype_and_ext` filter.\n4.  **Vulnerable Logic:**\n    *   The function retrieves the list of \"Enhanced Multi-Format\" extensions from the database (e.g., `['avif']`).\n    *   It iterates through these extensions and checks the filename: `if (strpos($filename, $extension) !== false)`.\n    *   If found, it modifies the return array to set `type` (MIME) and `ext` to match the allowed extension, effectively \"blessing\" the file.\n5.  **Sink:** WordPress core accepts the file as a valid image but preserves the original `.php` extension during the final move to the `uploads` directory because the sanitization was bypassed by the filter's return value.\n\n## 4. Nonce Acquisition Strategy\nThis exploit requires a valid `_wpnonce` associated with the `media-form` action (used by `async-upload.php`).\n\n1.  **Authentication:** Log in as an Author-level user.\n2.  **Navigation:** Use `browser_navigate` to go to `wp-admin\u002Fmedia-new.php`.\n3.  **Extraction:**\n    *   The nonce is typically found in the `_wpnonce` field of the upload form or within the `plupload` configuration object.\n    *   **Action:** `browser_eval(\"wp.Uploader.defaults.multipart_params._wpnonce\")` or `browser_eval(\"document.querySelector('#_wpnonce').value\")`.\n    *   (Inferred) The localization key for media nonces in WordPress is often under the `_wpnonce` key in the global `pluploadL10n` or `wpUploaderInit` objects.\n\n## 5. Exploitation Strategy\n### Step 1: Configuration\nEnsure the plugin is configured to be vulnerable. This requires modifying plugin options to enable the specific feature.\n\n### Step 2: Payload Construction\nCreate a PHP file named `shell.avif.php`.\nContent: `\u003C?php phpinfo(); ?>`\n\n### Step 3: Upload Request\nSend a multipart\u002Fform-data request to `async-upload.php`.\n\n**Request Details:**\n*   **Method:** POST\n*   **URL:** `http:\u002F\u002FTARGET\u002Fwp-admin\u002Fasync-upload.php`\n*   **Headers:**\n    *   `Content-Type: multipart\u002Fform-data; boundary=----WebKitFormBoundary`\n*   **Body Parameters:**\n    *   `name`: `shell.avif.php`\n    *   `action`: `upload-attachment`\n    *   `_wpnonce`: `[EXTRACTED_NONCE]`\n    *   `async-upload`: `[FILE_CONTENT]`\n\n### Step 4: Execution\nAccess the uploaded file. WordPress stores uploads in `wp-content\u002Fuploads\u002FYYYY\u002FMM\u002F`.\nURL: `http:\u002F\u002FTARGET\u002Fwp-content\u002Fuploads\u002F[YEAR]\u002F[MONTH]\u002Fshell.avif.php`\n\n## 6. Test Data Setup\n1.  **User:** Create an Author user:\n    *   `wp user create attacker attacker@example.com --role=author --user_pass=password123`\n2.  **Plugin Settings (Crucial):**\n    *   Identify the option name for Swiss Toolkit (likely `swiss_toolkit_settings` or similar - (inferred)).\n    *   Enable the \"Enhanced Multi-Format Image Support\".\n    *   Add `avif` to the list of allowed extensions.\n    *   *Note:* If the UI is complex, use `wp option get` to find the correct structure and `wp option update` to set it.\n\n## 7. Expected Results\n*   **HTTP Response:** The `async-upload.php` endpoint should return a `200 OK` with a JSON object containing the attachment ID and the success status.\n*   **File System:** A file named `shell.avif.php` should exist in the `wp-content\u002Fuploads\u002F` directory.\n*   **Remote Code Execution:** Navigating to the file URL should execute the PHP code and display the `phpinfo()` output.\n\n## 8. Verification Steps\n1.  **Check for file existence via CLI:**\n    *   `find \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002F -name \"shell.avif.php\"`\n2.  **Verify via HTTP:**\n    *   `http_request('GET', 'http:\u002F\u002Flocalhost:8080\u002Fwp-content\u002Fuploads\u002F[YYYY]\u002F[MM]\u002Fshell.avif.php')`\n    *   Check if response body contains \"PHP Version\".\n\n## 9. Alternative Approaches\n*   **If `strpos` is used differently:** If the plugin checks the *start* of the string instead of just the presence, try naming the file `avif.php`.\n*   **Alternative Extension:** If `avif` is not enabled by default, try common alternatives like `webp`, `svg`, or `heic` if they appear in the plugin's settings.\n*   **Bypass `wp_check_filetype_and_ext` via Null Byte (Old PHP):** If the environment is running an ancient PHP version (unlikely), `shell.php%00.avif` might be attempted, though this vulnerability is described as a logic flaw in the string check.","The Swiss Toolkit For WP plugin for WordPress is vulnerable to arbitrary file upload in versions up to 1.4.6 because it uses the strpos() function to validate file extensions. This logic flaw allows authenticated attackers with Author-level permissions to bypass security filters and upload executable PHP files by including a permitted extension string anywhere in the filename.","\u002F* File: swiss-toolkit-for-wp\u002Fincludes\u002Fclass-swiss-toolkit-for-wp.php (inferred) *\u002F\n\n\u002F\u002F Hooked into wp_check_filetype_and_ext\npublic function upload_extension_files($data, $file, $filename, $mimes) {\n    $settings = get_option('swiss_toolkit_settings');\n    $allowed_extensions = $settings['allowed_formats'] ?? [];\n\n    foreach ($allowed_extensions as $extension) {\n        \u002F\u002F Vulnerable check: looks for existence anywhere in the string\n        if (strpos($filename, $extension) !== false) {\n            $data['ext'] = $extension;\n            $data['type'] = 'image\u002F' . $extension;\n            break;\n        }\n    }\n    return $data;\n}","--- a\u002Fswiss-toolkit-for-wp\u002Fincludes\u002Fclass-swiss-toolkit-for-wp.php\n+++ b\u002Fswiss-toolkit-for-wp\u002Fincludes\u002Fclass-swiss-toolkit-for-wp.php\n@@ -10,7 +10,8 @@\n     $allowed_extensions = $settings['allowed_formats'] ?? [];\n \n     foreach ($allowed_extensions as $extension) {\n-        if (strpos($filename, $extension) !== false) {\n+        $file_ext = pathinfo($filename, PATHINFO_EXTENSION);\n+        if (strtolower($file_ext) === strtolower($extension)) {\n             $data['ext'] = $extension;\n             $data['type'] = 'image\u002F' . $extension;\n             break;","An authenticated user with Author-level access or higher can exploit this vulnerability if the 'Enhanced Multi-Format Image Support' feature is enabled. The attacker identifies an allowed extension (e.g., 'avif') and uploads a PHP file with a double extension, such as 'shell.avif.php', through the WordPress media uploader (\u002Fwp-admin\u002Fasync-upload.php). Because the plugin's validation logic only checks for the presence of the 'avif' string anywhere in the filename using strpos(), it marks the file as valid. WordPress then saves the file to the uploads directory with its original .php extension, allowing the attacker to execute arbitrary code by navigating to the file's URL.","gemini-3-flash-preview","2026-07-15 08:51:45","2026-07-15 08:52:16",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fswiss-toolkit-for-wp\u002Ftags"]