Robo Gallery <= 5.1.2 - Authenticated (Contributor+) Stored Cross-Site Scripting
Description
The Robo Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 5.1.2 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=5.1.2What Changed in the Fix
Changes introduced in v5.1.3
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-32356 (Robo Gallery Stored XSS) ## 1. Vulnerability Summary The **Robo Gallery** plugin for WordPress (versions <= 5.1.2) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin fails to sufficiently sanitize and es…
Show full research plan
Exploitation Research Plan - CVE-2026-32356 (Robo Gallery Stored XSS)
1. Vulnerability Summary
The Robo Gallery plugin for WordPress (versions <= 5.1.2) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists because the plugin fails to sufficiently sanitize and escape gallery settings and metadata before rendering them in the admin dashboard and on the front-end via shortcodes. Specifically, an authenticated attacker with Contributor-level permissions or higher can inject malicious JavaScript into gallery configuration fields (stored as postmeta). When an administrator or any site visitor views a page containing the gallery, the script executes in their browser context.
2. Attack Vector Analysis
- Vulnerable Post Type:
robo_gallery(defined by the constantROBO_GALLERY_TYPE_POST). - Endpoint:
wp-admin/post.php(Standard WordPress post/meta update) or the plugin's AJAX save handlers. - Vulnerable Parameters:
post_title(if the plugin echoes it without escaping in the gallery view).- Meta fields prefixed with
robo_gallery_, such asrobo_gallery_gallery_type_sourceor image-specific metadata.
- Authentication: Required (Contributor+). Contributors can create and edit their own
robo_galleryposts. - Preconditions: The attacker must be able to create or edit a
robo_gallerypost and place its shortcode[robo-gallery id="..."]on a page they can publish (or wait for an admin to view the gallery).
3. Code Flow
- Input: A Contributor sends a POST request to
wp-admin/post.phpwithaction=editpost, including a malicious payload in the title ormeta_input. - Storage: WordPress (or the plugin's
save_postlogic) saves the payload into thewp_poststable (for title) orwp_postmetatable (for settings). - Retrieval: When the shortcode
[robo-gallery]is processed, the plugin callsget_post_metato retrieve gallery settings. - Sink: The plugin uses
rbsGalleryClassView::render(defined inapp/class.view.php) to extract these variables into a template. - Execution: The template (e.g., in
extensions/galleryType/) echoes the retrieved meta values without usingesc_html()oresc_attr(), leading to XSS.
4. Nonce Acquisition Strategy
To save changes to a gallery, a Contributor needs a valid WordPress _wpnonce.
- Identify Entry Point: Contributors can access the "Gallery" menu in the WordPress dashboard.
- Create Post: Create a draft gallery to get a valid Post ID.
- Navigate: Use
browser_navigatetowp-admin/post.php?post=[ID]&action=edit. - Extract Nonce: Use
browser_evalto extract the_wpnoncefrom the hidden input field in the#postform.- JavaScript:
document.querySelector('input[name="_wpnonce"]').value
- JavaScript:
- AJAX Nonce (Optional): If the plugin uses AJAX for settings, the nonce is often localized in a script. Based on
app/class.listing.php, look for the variablerobo-gallery-lising-jsor similar inwp_localize_script.
5. Exploitation Strategy
Step 1: Create a Gallery Post
Use WP-CLI to create a gallery post as a Contributor.
wp post create --post_type=robo_gallery --post_status=publish --post_title="Initial Gallery" --post_author=[CONTRIBUTOR_ID]
Step 2: Extract Nonce and Post ID
Navigate to the edit page of the newly created gallery to capture the _wpnonce.
Step 3: Inject Payload via editpost
Send a POST request to wp-admin/post.php to update the gallery with XSS payloads.
HTTP Request:
- URL:
http://[TARGET]/wp-admin/post.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body:
action=editpost
&post_ID=[GALLERY_ID]
&_wpnonce=[EXTRACTED_NONCE]
&post_title=Test Gallery <script>alert('XSS_IN_TITLE')</script>
&meta_input[robo_gallery_gallery_type_source]=<script>alert('XSS_IN_META')</script>
&meta_input[robo_gallery_gallery_type]=grid
Step 4: Embed Gallery in a Public Page
As the Contributor, create a public page that renders this gallery.
wp post create --post_type=page --post_status=publish --post_title="Gallery Page" --post_content='[robo-gallery id="[GALLERY_ID]"]'
Step 5: Trigger XSS
Navigate to the URL of the "Gallery Page" as an unauthenticated user or an Admin to trigger the execution.
6. Test Data Setup
- Users:
- Contributor:
username: contributor,password: password123
- Contributor:
- Plugin: Robo Gallery (slug:
robo-gallery) version 5.1.2 installed and active. - Content: One
robo_gallerypost and onepagepost containing the shortcode.
7. Expected Results
- When the page containing the
[robo-gallery]shortcode is loaded, a browser alert dialog should appear with the text'XSS_IN_TITLE'or'XSS_IN_META'. - Inspection of the page source should show the raw
<script>tags injected into the HTML without being encoded as<script>.
8. Verification Steps
- Verify Storage: Use WP-CLI to check if the payload is in the database.
wp post get [GALLERY_ID] --field=post_title wp post meta get [GALLERY_ID] robo_gallery_gallery_type_source - Verify Output: Use
http_requestto fetch the public page and grep for the script.# Use the http_request tool and check for: # <script>alert('XSS_IN_TITLE')</script>
9. Alternative Approaches
- Image Title XSS: If the gallery settings are sanitized, try injecting the payload into the "Title" or "Caption" of an image attached to the gallery. This is often handled via the
wp_ajax_robo_gallery_save_image_data(inferred) AJAX action. - Admin Dashboard XSS: Check if the payload executes in
wp-admin/edit.php?post_type=robo_gallery.app/class.listing.phpsuggests custom columns are added. If any of these columns (like a "Gallery Preview" or "Description") echo meta, the XSS will fire when an Admin views the gallery list.
Summary
The Robo Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) in versions up to and including 5.1.2. Authenticated attackers with Contributor-level access or higher can inject malicious JavaScript into gallery configuration fields or post titles, which then execute in the browser context of any user viewing the gallery.
Vulnerable Code
// app/class.utils.php line 125 static function getSourceGallery($galleryId = 0) { $fieldName = ROBO_GALLERY_PREFIX . 'gallery_type'; $galleryType = ''; if (isset($_GET[$fieldName]) && $_GET[$fieldName]) { $galleryType = preg_replace("/[^A-Za-z-0-9]/", "", $_GET[$fieldName]); } if (!$galleryId) { $galleryId = self::getIdGallery(); } if ($galleryId) { $galleryType_temp = get_post_meta($galleryId, $fieldName . '_source', true); if ($galleryType_temp) { $galleryType = $galleryType_temp; } } return $galleryType; } --- // app/class.view.php line 30 public function render($template, array $vars = array()) { $templatePath = $this->templatePath . $template . '.tpl.php'; if (!file_exists($templatePath)) { throw new Exception( "Could not find template. Template: {$template}"); } extract($vars); require $templatePath; }
Security Fix
@@ -2,7 +2,7 @@ /* * Robo Gallery -* Version: 5.1.0 - 50521 +* Version: 5.1.2 - 54264 * By Robosoft * * Contact: https://robogallery.co/ ... (truncated)
Exploit Outline
To exploit this vulnerability, an attacker with Contributor-level permissions must first create or edit a 'robo_gallery' post type. By navigating to the edit page (wp-admin/post.php?post=[ID]&action=edit), the attacker captures a valid WordPress nonce. The attacker then submits a POST request to wp-admin/post.php using the 'editpost' action, embedding a script payload within the 'post_title' or gallery-specific meta fields such as 'meta_input[robo_gallery_gallery_type_source]'. Once saved, the attacker places the gallery shortcode [robo-gallery id="..."] on a page they can publish. When an administrator or visitor views that page, the plugin retrieves the malicious meta values and renders them without proper sanitization or escaping, triggering the execution of the injected script.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.