[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fu4dkMiEOePVyYPYLN0uISKyBCmN4vXsej7gdnn2FvLg":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":31,"research_fix_diff":32,"research_exploit_outline":33,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":37},"CVE-2026-42656","contest-gallery-upload-vote-photos-media-sell-with-paypal-stripe-authenticated-subscriber-stored-cross-site-scripting","Contest Gallery – Upload & Vote Photos, Media, Sell with PayPal & Stripe \u003C= 28.1.6 - Authenticated (Subscriber+) Stored Cross-Site Scripting","The Contest Gallery – Upload & Vote Photos, Media, Sell with PayPal & Stripe plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 28.1.6 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with subscriber-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","contest-gallery",null,"\u003C=28.1.6","29.0.0","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-04-29 00:00:00","2026-05-04 13:56:26",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa1525119-732d-4948-9c33-75e9f3517c0d?source=api-prod",6,[22,23,24,25],"ajax\u002Fajax-functions-backend.php","ajax\u002Fajax-functions-frontend.php","changelog.txt","check-language-ecommerce.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-42656 (Contest Gallery Stored XSS)\n\n## 1. Vulnerability Summary\nThe **Contest Gallery** plugin (up to 28.1.6) contains a stored cross-site scripting vulnerability. The flaw exists because authenticated users (Subscriber level and above) can access certain AJAX endpoints that update gallery configurations or entry data without sufficient capability checks (`current_user_can`). Input provided to these endpoints is inadequately sanitized before being stored in the database, and is subsequently rendered on both frontend and backend pages without proper escaping.\n\n## 2. Attack Vector Analysis\n- **Vulnerable Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Primary AJAX Action**: `post_cg_save_gallery_options_general` (inferred from plugin architecture) or `post_cg_save_entry_details`.\n- **Payload Parameter**: `cg_gallery_name` or `cg_entry_name`.\n- **Authentication**: Subscriber level (authenticated).\n- **Preconditions**: A gallery must exist (e.g., ID 1) and the attacker must obtain a valid nonce.\n\n## 3. Code Flow\n1. **Entry Point**: A Subscriber sends a POST request to `admin-ajax.php` with an action prefix `wp_ajax_post_cg_...`.\n2. **Nonce Verification**: The function `cg_check_nonce()` (called at the start of backend AJAX handlers in `ajax\u002Fajax-functions-backend.php`) verifies the nonce provided in the `cgNonce` parameter.\n3. **Missing Capability Check**: The handler lacks a `current_user_can('manage_options')` check, allowing Subscribers to bypass administrative restrictions.\n4. **Data Persistence**: The handler processes the `$_POST` array (often using `cg1l_sanitize_post` which is bypassable for HTML tags) and updates the database table `{$wpdb->prefix}contest_gal1ery` or `{$wpdb->prefix}contest_gal1ery_entries`.\n5. **Sink**: When an admin or any visitor views the gallery, the plugin retrieves the settings using `$wpdb->get_row` and echoes the name directly into the page or inside a script block (as seen in `post_cg_get_current_permalinks`).\n\n## 4. Nonce Acquisition Strategy\nThe plugin enqueues its nonces via `wp_localize_script`. For Subscribers, the nonce is often available on the frontend if a gallery shortcode is present, or in the dashboard if the plugin loads scripts there.\n\n1.  **Identify Shortcode**: The primary shortcode is `[cg_gallery id=\"1\"]`.\n2.  **Create Test Page**: Create a public page containing this shortcode to force the plugin to enqueue its assets.\n3.  **Navigate and Extract**: Use the browser to navigate to this page and extract the nonce from the `cgJsClass` or `cg_ajax_object` global variables.\n\n- **Variable Name**: `cgJsClass.gallery.vars.currentCgNonce` (from `ajax-functions-frontend.php`) or `cg_ajax_object.nonce`.\n- **Action String**: `cg1l_action` or `contest-gal1ery-nonce`.\n\n## 5. Exploitation Strategy\n### Step 1: Obtain Nonce\nUse `browser_navigate` to visit a page with the gallery shortcode and `browser_eval` to extract the nonce.\n\n### Step 2: Inject Payload\nSubmit a request to update the gallery title with an XSS payload.\n\n- **URL**: `http:\u002F\u002Fvulnerable-wp.local\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method**: POST\n- **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Parameters**:\n    - `action`: `post_cg_save_gallery_options_general`\n    - `cgNonce`: `[EXTRACTED_NONCE]`\n    - `cgRealId`: `1` (The ID of the target gallery)\n    - `cg_gallery_name`: `Test Gallery\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n\n### Step 3: Trigger Execution\nNavigate to the gallery page or the plugin's admin settings page as an administrator.\n\n## 6. Test Data Setup\n1.  **Create Gallery**: Use WP-CLI to ensure at least one gallery exists.\n    ```bash\n    # This usually requires direct DB insertion as the plugin doesn't provide CLI\n    wp db query \"INSERT INTO wp_contest_gal1ery (GalleryID, GalleryName) VALUES (1, 'Initial Gallery');\"\n    ```\n2.  **Create Landing Page**:\n    ```bash\n    wp post create --post_type=page --post_title=\"Gallery Page\" --post_status=publish --post_content='[cg_gallery id=\"1\"]'\n    ```\n3.  **Create Attacker User**:\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber --user_pass=password\n    ```\n\n## 7. Expected Results\n- The AJAX request should return a successful status (e.g., `1` or a JSON success message).\n- The database field `GalleryName` in the `wp_contest_gal1ery` table will contain the `\u003Cscript>` tag.\n- Upon viewing the page at `?page_id=[ID]`, a JavaScript alert box showing the document domain should appear.\n\n## 8. Verification Steps\n1.  **Check Database**:\n    ```bash\n    wp db query \"SELECT GalleryName FROM wp_contest_gal1ery WHERE id=1;\"\n    ```\n2.  **Verify Frontend Output**:\n    Use `http_request` to fetch the gallery page and check for the raw payload.\n    ```bash\n    # Expected in response body:\n    # \u003Ch2>Test Gallery\u003Cscript>alert(document.domain)\u003C\u002Fscript>\u003C\u002Fh2>\n    ```\n\n## 9. Alternative Approaches\nIf `post_cg_save_gallery_options_general` is restricted:\n- **Target Entry Submission**: If Subscribers are allowed to submit photos, use an action like `post_cg_save_entry_details` and inject into the entry title or description.\n- **Payload Variant**: If `\u003Cscript>` is filtered, try:\n    - `\u003Cimg src=x onerror=alert(1)>`\n    - `\">\u003Csvg\u002Fonload=alert(1)>`\n- **Check Backend XSS**: Some payloads might only execute in the admin dashboard (Stored Blind XSS) where the gallery list is rendered. Navigate to `\u002Fwp-admin\u002Fadmin.php?page=contest-gallery-management` to verify.","The Contest Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via its AJAX handlers because it lacks proper capability checks (e.g., current_user_can) and fails to adequately sanitize or escape gallery configuration data. This allows authenticated attackers with Subscriber-level access to modify gallery settings and inject arbitrary JavaScript that executes when an administrator or visitor views the affected gallery page.","\u002F\u002F ajax\u002Fajax-functions-backend.php @ line 4 (version 28.1.7)\nadd_action('wp_ajax_post_cg_get_current_permalinks', 'post_cg_get_current_permalinks');\nif (!function_exists('post_cg_get_current_permalinks')) {\n    function post_cg_get_current_permalinks() {\n\n        cg_check_nonce(); \u002F\u002F Vulnerability: This function only verifies the nonce, not user capabilities.\n\n        global $wpdb;\n        $tablename = $wpdb->prefix . \"contest_gal1ery\";\n        $realId = absint($_POST['cgRealId']);\n        $realIdRow = $wpdb->get_row( \"SELECT * FROM $tablename WHERE id='$realId'\" );\n\n--- \n\n\u002F\u002F ajax\u002Fajax-functions-backend.php @ line 54 (version 28.1.7)\nadd_action('wp_ajax_post_cg_create_pdf_preview_backend', 'post_cg_create_pdf_preview_backend');\nif (!function_exists('post_cg_create_pdf_preview_backend')) {\n    function post_cg_create_pdf_preview_backend($WpUpload = 0, $realId = 0, $cg_base_64 = '', $isFromFrontendUpload = false) {\n\n        cg_check_nonce(); \u002F\u002F Vulnerability: Allows Subscriber+ users to trigger backend logic.\n\n        global $wpdb;\n        $tablename_posts = $wpdb->prefix . \"posts\";\n        $tablename_wp_pdf_previews = $wpdb->prefix . \"contest_gal1ery_pdf_previews\";","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcontest-gallery\u002F28.1.7\u002Fajax\u002Fajax-functions-backend.php\t2026-04-06 19:43:48.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcontest-gallery\u002F29.0.0\u002Fajax\u002Fajax-functions-backend.php\t2026-04-19 21:25:02.000000000 +0000\n@@ -1,10 +1,60 @@\n \u003C?php\n+if (!function_exists('cg_backend_ajax_require_access_json')) {\n+    function cg_backend_ajax_require_access_json() {\n+        if (!defined('DOING_AJAX') || !DOING_AJAX) {\n+            cg_backend_ajax_error_json('Invalid AJAX request.', 400, 'cg_invalid_ajax_request');\n+        }\n+\n+        if (!is_user_logged_in() || !cg_user_has_backend_access()) {\n+            cg_backend_ajax_error_json('This area can be edited only as administrator, editor or author.', 403, 'cg_missing_rights');\n+        }\n+\n+        $cg_nonce = '';\n+        if (isset($_POST['cg_nonce'])) {\n+            $cg_nonce = sanitize_text_field($_POST['cg_nonce']);\n+        } elseif (isset($_GET['cg_nonce'])) {\n+            $cg_nonce = sanitize_text_field($_GET['cg_nonce']);\n+        }\n+\n+        if (empty($cg_nonce) || !wp_verify_nonce($cg_nonce, 'cg_nonce')) {\n+            wp_send_json_error(array(\n+                'message' => 'WP nonce security token not set or not valid anymore.',\n+                'code' => 'cg_nonce_invalid',\n+                'version' => cg_get_version()\n+            ), 403);\n+        }\n+    }\n+}\n+\n \u002F\u002F post_cg_get_current_permalinks\n add_action('wp_ajax_post_cg_get_current_permalinks', 'post_cg_get_current_permalinks');\n if (!function_exists('post_cg_get_current_permalinks')) {\n     function post_cg_get_current_permalinks() {\n \n-        cg_check_nonce();\n+        cg_require_backend_access();","The exploit involves an authenticated attacker with at least Subscriber-level privileges leveraging a missing capability check in administrative AJAX actions. \n\n1. Authentication: The attacker logs in as a Subscriber.\n2. Nonce Acquisition: The attacker obtains a valid WordPress nonce (action: 'cg_nonce' or similar) by inspecting the source code of a page containing a gallery shortcode, where the plugin enqueues nonces via `wp_localize_script` (e.g., inside the `cgJsClass` object).\n3. Payload Injection: The attacker sends a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with an action intended for gallery configuration (e.g., `post_cg_save_gallery_options_general`). The request includes a malicious XSS payload (e.g., `\u003Cscript>alert(1)\u003C\u002Fscript>`) in parameters like `cg_gallery_name`.\n4. Storage: Because the AJAX handler only verifies the nonce and does not check for the 'manage_options' capability, the malicious input is saved to the database.\n5. Execution: The payload executes whenever an administrator visits the gallery management page or a user visits the modified gallery frontend.","gemini-3-flash-preview","2026-05-04 17:55:08","2026-05-04 17:56:40",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","28.1.7","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontest-gallery\u002Ftags\u002F28.1.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcontest-gallery.28.1.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontest-gallery\u002Ftags\u002F29.0.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcontest-gallery.29.0.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontest-gallery\u002Ftags"]