[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fSRPsMBpKdBgUKWEh-S8rmFQQkl4KHA3qAqhu_0iPWOI":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":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-12923","video-gallery-authenticated-subscriber-arbitrary-function-call-via-path-parameter","Video Gallery \u003C= 4.0.3 - Authenticated (Subscriber+) Arbitrary Function Call via 'path' Parameter","The Youtube Showcase plugin for WordPress is vulnerable to Arbitrary Function Call in versions up to and including 4.0.3. This is due to insufficient validation of the 'path' parameter in the emd_delete_file() AJAX handler in includes\u002Fcommon-functions.php. The user-supplied value is passed through sanitize_text_field(), has its trailing '_PLUGIN_DIR' substring stripped, and is then invoked as a PHP function name with no arguments via `$sess_name()`. The handler is gated only by a nonce — no current_user_can() check is present — and the nonce is emitted on any front-end page that renders a form shortcode containing file fields. This makes it possible for authenticated attackers, with Subscriber-level access and above, to invoke arbitrary zero-argument PHP functions (such as phpinfo, phpversion, get_defined_vars, error_get_last), resulting in sensitive information disclosure and potential further compromise depending on the functions available in the environment.","youtube-showcase",null,"\u003C=4.0.3","4.0.4","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Improper Control of Filename for Include\u002FRequire Statement in PHP Program ('PHP Remote File Inclusion')","2026-06-30 15:01:25","2026-07-01 03:43:37",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fbe4743d5-e4ca-4579-84e2-5eb3ef0e274d?source=api-prod",1,[22,23,24],"includes\u002Fcommon-functions.php","readme.txt","youtube-showcase.php","researched",false,3,"This research plan outlines the technical steps required to demonstrate the arbitrary function call vulnerability (CVE-2026-12923) in the **Youtube Showcase** plugin.\n\n### 1. Vulnerability Summary\nThe `Youtube Showcase` plugin (up to 4.0.3) contains an authenticated arbitrary function call vulnerability in its AJAX handler `emd_delete_file()`. The vulnerability stems from a lack of validation on the `path` parameter. The user-controlled string is processed to remove a specific suffix and then executed directly as a PHP function name. Because the handler lacks capability checks (e.g., `current_user_can()`), any authenticated user with Subscriber-level access can invoke zero-argument PHP functions.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `emd_delete_file` (inferred from function name)\n*   **HTTP Method:** POST\n*   **Vulnerable Parameter:** `path`\n*   **Authentication:** Required (Subscriber+)\n*   **Precondition:** A valid nonce must be obtained from a front-end page rendering a form with file fields.\n\n### 3. Code Flow\n1.  **Entry Point:** The AJAX action `wp_ajax_emd_delete_file` (and potentially `wp_ajax_nopriv_emd_delete_file`) is registered, pointing to the function `emd_delete_file` in `includes\u002Fcommon-functions.php`.\n2.  **Input Handling:** The function retrieves `$_POST['path']`.\n3.  **Sanitization:** The input is passed through `sanitize_text_field()`.\n4.  **Transformation:** The code performs a string replacement: `$sess_name = str_replace('_PLUGIN_DIR', '', $path);` (as per the vulnerability description).\n5.  **The Sink:** The resulting variable is invoked as a dynamic function call: `$sess_name();`.\n6.  **Constraint:** The function called must accept zero arguments to avoid a `ArgumentCountError` in PHP 7.1+.\n\n### 4. Nonce Acquisition Strategy\nThe vulnerability description states the nonce is emitted on front-end pages containing form shortcodes with file fields. Based on the plugin structure (`includes\u002Fentities\u002Femd-video-shortcodes.php`), the relevant shortcode is likely used for video submissions.\n\n1.  **Identify Shortcode:** The plugin likely uses `[youtube_showcase_video_form]` or `[emd_video_form]` (inferred).\n2.  **Setup Page:** Create a public page containing this shortcode.\n    ```bash\n    wp post create --post_type=page --post_title=\"Submit Video\" --post_status=publish --post_content='[youtube_showcase_video_form]'\n    ```\n3.  **Navigate and Extract:**\n    *   Login as a Subscriber.\n    *   Navigate to the newly created page.\n    *   Use `browser_eval` to locate the nonce. In eMarket Design plugins, AJAX variables are typically localized under a global object like `emd_ajax_vars` or `wpas_ajax_vars`.\n    *   **Likely Key:** `window.emd_ajax_vars?.nonce` or `window.wpas_ajax_vars?.nonce`.\n    *   **Specific Search:** Check the page source for `wp_create_nonce('emd_delete_file')` or similar.\n\n### 5. Exploitation Strategy\nThe goal is to trigger `phpinfo()` to prove arbitrary code execution\u002Finformation disclosure.\n\n*   **Request URL:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Payload:**\n    *   `action`: `emd_delete_file`\n    *   `path`: `phpinfo_PLUGIN_DIR` (The `_PLUGIN_DIR` suffix will be stripped, leaving `phpinfo`)\n    *   `nonce`: `[EXTRACTED_NONCE]`\n\n**HTTP Request Example:**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nHost: localhost\nContent-Type: application\u002Fx-www-form-urlencoded\nCookie: wordpress_logged_in_...\n\naction=emd_delete_file&path=phpinfo_PLUGIN_DIR&nonce=a1b2c3d4e5\n```\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Install and activate `youtube-showcase` version 4.0.3.\n2.  **Create User:**\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber --user_pass=password\n    ```\n3.  **Identify Form Page:** If the plugin’s \"Setup Assistant\" was used, it may have already created a \"Video Submission\" or \"Add Video\" page. If not, create one using the steps in Section 4.\n\n### 7. Expected Results\n*   **Successful Exploit:** The server response should contain the standard PHP Information (`phpinfo`) HTML output.\n*   **Alternative PoC:** Using `path=get_defined_vars_PLUGIN_DIR` should return a serialized or dumped list of defined variables (depending on how the plugin handles the function's return value).\n\n### 8. Verification Steps\nSince this is an arbitrary function call, verification is best done by observing the HTTP response:\n1.  Verify the presence of the string `PHP Version` in the response body.\n2.  Verify the presence of the string `Configuration` or `Environment` in the response body.\n\n### 9. Alternative Approaches\nIf `phpinfo()` is disabled or filtered, attempt to trigger functions that provide confirmation without extensive output:\n*   **`path=error_get_last_PLUGIN_DIR`**: Might disclose sensitive file paths if errors occurred.\n*   **`path=phpversion_PLUGIN_DIR`**: Returns the PHP version string.\n*   **`path=wp_get_current_user_PLUGIN_DIR`**: May return user object data if the plugin echoes the result of the dynamic call.\n\n**Note on `_PLUGIN_DIR`:** If the `str_replace` logic is `str_replace('_PLUGIN_DIR', '', $path)`, sending `phpinfo_PLUGIN_DIR` is mandatory. If the logic simply permits any string and `_PLUGIN_DIR` happens to be part of a path the developer *intended* to use, then `path=phpinfo` alone might work. The researcher should test both.","The YouTube Showcase plugin for WordPress is vulnerable to an authenticated arbitrary function call due to the unsafe use of dynamic function names in the emd_delete_file() AJAX handler. An attacker with Subscriber-level permissions or higher can provide a crafted path parameter which is processed and then executed as a PHP function call. This allows for sensitive information disclosure (e.g., via phpinfo) or other actions depending on the environment's available PHP functions.","\u002F\u002F includes\u002Fcommon-functions.php\n\n\t\t$path = sanitize_text_field($_POST['path']);\n\t\t$myapp = strtolower(preg_replace('\u002F_PLUGIN_DIR$\u002F','',$path));\n\t\t$sess_name = strtoupper($myapp);\n\t\t$session_class = $sess_name();","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.3\u002Fincludes\u002Fcommon-functions.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.4\u002Fincludes\u002Fcommon-functions.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.3\u002Fincludes\u002Fcommon-functions.php\t2026-06-20 16:31:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.4\u002Fincludes\u002Fcommon-functions.php\t2026-06-27 15:47:18.000000000 +0000\n@@ -1062,24 +1062,35 @@\n \t\t$ret = check_ajax_referer('emd_delete_file', 'nonce', false);\n \t\tif ($ret === false) {\n \t\t\techo '\u003Cdiv class=\"text-danger\">\u003Ca href=\"' . wp_get_referer() . '\">' . esc_html__('Please refresh the page and try again.', 'youtube-showcase') . '\u003C\u002Fa>\u003C\u002Fdiv>';\n-\t\t\tdie();\n+\t\t\twp_die();\n \t\t}\n-\t\t$path = sanitize_text_field($_POST['path']);\n-\t\t$myapp = strtolower(preg_replace('\u002F_PLUGIN_DIR$\u002F','',$path));\n+\t\t$myapp = 'youtube_showcase';\n \t\t$sess_name = strtoupper($myapp);\n-\t\t$session_class = $sess_name();\n+\t\tif ( function_exists($sess_name) ) {\n+\t\t\t$session_class = $sess_name();\n+\t\t} else {\n+\t\t\techo '\u003Cdiv class=\"text-danger\">' . esc_html__('System configuration error.', 'youtube-showcase') . '\u003C\u002Fdiv>';\n+\t\t\twp_die();\n+\t\t}\n+\t\tif ( ! $session_class || ! isset($session_class->session) ) {\n+\t\t\techo '\u003Cdiv class=\"text-danger\">' . esc_html__('Session handler unavailable.', 'youtube-showcase') . '\u003C\u002Fdiv>';\n+\t\t\twp_die();\n+\t\t}\n \t\t$sess_files = $session_class->session->get('uploads');\n-\t\t$field = sanitize_text_field($_POST['field']);\n-\t\tif(!empty($sess_files[$field])){\n-\t\t\tforeach($sess_files[$field] as $kattch => $myattch){\n-\t\t\t\tif($myattch['name'] == sanitize_text_field($_POST['del_file'])){\n+\t\t$field = isset($_POST['field']) ? sanitize_text_field($_POST['field']) : '';\n+\t\tif ( ! empty( $sess_files[$field] ) && isset( $_POST['del_file'] ) ) {\n+\t\t\t$del_file_target = sanitize_text_field($_POST['del_file']);\n+\n+\t\t\tforeach ( $sess_files[$field] as $kattch => $myattch ) {\n+\t\t\t\tif ( isset($myattch['full_path']) && $myattch['full_path'] === $del_file_target ) {\n \t\t\t\t\tunset($sess_files[$field][$kattch]);\n \t\t\t\t}\n \t\t\t}\n-\t\t\t$session_class->session->set('uploads',$sess_files);\n+\t\t\t\u002F\u002F Update the user's specific session\n+\t\t\t$session_class->session->set('uploads', $sess_files);\n \t\t}\n \t\techo 1;\n-\t\tdie();\n+\t\twp_die();\n \t}\n }\n if(!function_exists('emd_get_attachment_layout')){\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.3\u002Freadme.txt \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.4\u002Freadme.txt\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.3\u002Freadme.txt\t2026-06-20 16:53:06.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.4\u002Freadme.txt\t2026-06-27 15:47:18.000000000 +0000\n@@ -3,7 +3,7 @@\n Tags: video gallery, youtube, playlist, youtube gallery, youtube channel\n Requires at least: 5.8\n Tested up to: 7.0\n-Stable tag: 4.0.3\n+Stable tag: 4.0.4\n License: GPLv2 or later\n License URI: http:\u002F\u002Fwww.gnu.org\u002Flicenses\u002Fgpl-2.0.html\n Plugin URI: https:\u002F\u002Femdplugins.com\u002Fyoutube-showcase\n@@ -103,6 +103,8 @@\n 9. CSV Import\u002FExport – Bulk manage your library with the eMD CSV Extension for high-volume sites.\n \n == Changelog ==\n+= 4.0.4 =\n+* FIXED Function call vulnerability in the file deletion AJAX handler.\n = 4.0.3 =\n * FIXED Patched an unrestricted file upload vulnerability.\n = 4.0.2 =\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.3\u002Fyoutube-showcase.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.4\u002Fyoutube-showcase.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.3\u002Fyoutube-showcase.php\t2026-06-20 16:53:06.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fyoutube-showcase\u002F4.0.4\u002Fyoutube-showcase.php\t2026-06-27 15:47:18.000000000 +0000\n@@ -89,7 +89,7 @@\n \t\t * @return void\n \t\t *\u002F\n \t\tprivate function define_constants() {\n-\t\t\tdefine('YOUTUBE_SHOWCASE_VERSION', '4.0.3');\n+\t\t\tdefine('YOUTUBE_SHOWCASE_VERSION', '4.0.4');\n \t\t\tdefine('YOUTUBE_SHOWCASE_AUTHOR', 'eMarket Design');\n \t\t\tdefine('YOUTUBE_SHOWCASE_NAME', 'Youtube Showcase');\n \t\t\tdefine('YOUTUBE_SHOWCASE_PLUGIN_FILE', __FILE__);","To exploit this vulnerability, an attacker first authenticates with Subscriber-level privileges and visits a page containing the plugin's form shortcode to obtain a valid security nonce for the emd_delete_file action. The attacker then sends a POST request to the \u002Fwp-admin\u002Fadmin-ajax.php endpoint with the action parameter set to emd_delete_file, the nonce parameter set to the extracted value, and the path parameter set to a desired function name followed by the _PLUGIN_DIR suffix (e.g., phpinfo_PLUGIN_DIR). The server-side code strips the suffix and executes the resulting string as a PHP function, returning the function's output in the HTTP response.","gemini-3-flash-preview","2026-07-25 13:11:25","2026-07-25 13:11:54",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","4.0.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fyoutube-showcase\u002Ftags\u002F4.0.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fyoutube-showcase.4.0.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fyoutube-showcase\u002Ftags\u002F4.0.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fyoutube-showcase.4.0.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fyoutube-showcase\u002Ftags"]