Robin Image Optimizer <= 2.0.2 - Authenticated (Author+) Stored Cross-Site Scripting via Image Alternative Text Field
Description
The Robin Image Optimizer – Unlimited Image Optimization & WebP Converter plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'Alternative Text' field of a Media Library image in all versions up to, and including, 2.0.2 due to insufficient input sanitization and output escaping. 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 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
<=2.0.2Source Code
WordPress.org SVNThis research plan targets **CVE-2026-1319**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Robin Image Optimizer** plugin for WordPress. ## 1. Vulnerability Summary The Robin Image Optimizer plugin (<= 2.0.2) fails to sufficiently sanitize and escape the **Alternative Text** (alt text…
Show full research plan
This research plan targets CVE-2026-1319, a Stored Cross-Site Scripting (XSS) vulnerability in the Robin Image Optimizer plugin for WordPress.
1. Vulnerability Summary
The Robin Image Optimizer plugin (<= 2.0.2) fails to sufficiently sanitize and escape the Alternative Text (alt text) field of images in the Media Library. While WordPress core provides some protections, the plugin likely hooks into image rendering or optimization logs to display this metadata. An authenticated user with Author privileges or higher can inject a malicious script into the Alt Text field. This script is stored in the database (usually as _wp_attachment_image_alt post meta) and executes when an administrative user views the plugin's optimization reports or when the plugin renders the image on the frontend (e.g., during WebP conversion or lazy loading).
2. Attack Vector Analysis
- Vulnerable Endpoint:
wp-admin/admin-ajax.php(Standard WordPress media update) or the plugin's optimization dashboard. - Action:
save-attachment(Core WP) or a plugin-specific AJAX action if they provide a custom edit interface. - Vulnerable Parameter:
changes[alt_text__column]oralt(depending on the AJAX handler). - Authentication: Required (Author level or higher). Authors can upload images and modify their metadata.
- Preconditions: Robin Image Optimizer must be active. The XSS typically triggers when the plugin processes the image or displays optimization logs.
3. Code Flow
- Entry Point: An Author updates an image's "Alternative Text" via the Media Library.
- Storage: The input is saved to the
wp_postmetatable under the key_wp_attachment_image_alt. - Processing: The plugin (Robin Image Optimizer) retrieves this meta during optimization or when building its "Optimization Statistics" or "Image Comparison" views.
- Sink: The plugin outputs the metadata without calling
esc_attr()oresc_html().- Potential Sink 1: The plugin's comparison tool (likely
admin/views/image-statistics.phpor similar). - Potential Sink 2: Frontend rendering logic where the plugin replaces standard
<img>tags with WebP/optimized versions (likely inincludes/classes/class-rio-image-statistic.phporincludes/classes/class-rio-attachment.php).
- Potential Sink 1: The plugin's comparison tool (likely
4. Nonce Acquisition Strategy
Since this exploit requires Author-level authentication to update Media, we must acquire the standard WordPress Media nonces.
- Login: Log in as an Author.
- Navigate: Use
browser_navigateto go to the Media Library:/wp-admin/upload.php. - Extract Nonce: The
save-attachmentaction requires a nonce typically found in thewp.mediaJavaScript object or localized variables.- Action:
browser_eval("wp.media.model.settings.post.nonce")or inspecting the_wpnoncein the edit attachment modal.
- Action:
- Plugin Specifics: Check if Robin Image Optimizer localizes its own nonce for its dashboard.
- Target Variable:
window.wio_optimization?.nonce(inferred prefix for Robin Image Optimizer).
- Target Variable:
5. Exploitation Strategy
We will exploit this by updating an existing attachment's alternative text via the standard AJAX interface.
Step 1: Upload and Get ID
As an Author, upload a test image to get an attachment_id.
Step 2: Inject Payload
Send an AJAX request to update the Alt Text.
- Tool:
http_request - URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body:
action=save-attachment&id=[ATTACHMENT_ID]&_wpnonce=[NONCE]&changes[alt_text__column]=<img src=x onerror=alert("CVE-2026-1319")>
Step 3: Trigger Execution
The payload needs to be rendered. We will test two triggers:
- Admin Dashboard: Navigate to the Robin Image Optimizer "Bulk Optimization" page:
/wp-admin/admin.php?page=bulk_optimization-robin-image-optimizer. This page often lists images and their optimization status. - Frontend: Create a post containing the image and view it. Robin Image Optimizer will process the
<img>tag and may output the unsanitized alt text in its optimized HTML.
6. Test Data Setup
- User: Create a user with the Author role.
- Image: Upload a standard
.jpgor.pngto the Media Library. - Post: Create a public post that includes this image.
- Plugin Config: Ensure "WebP Conversion" or "Image Optimization" is enabled in Robin Image Optimizer settings to ensure the plugin's code path for image replacement is active.
7. Expected Results
- Storage: The
_wp_attachment_image_altmeta for the image should contain the raw<img src=x onerror=...>string. - Execution: When an Admin visits the plugin's "Optimization" page, the browser should execute the
alert()call. - Response: The
admin-ajax.phprequest should return a JSON success message:{"success":true,"data":{...}}.
8. Verification Steps
- Database Check: Use WP-CLI to verify the stored meta:
wp post meta get [ATTACHMENT_ID] _wp_attachment_image_alt - DOM Inspection: Navigate to the optimization page via
browser_navigateand check for the presence of the payload:browser_eval("document.body.innerHTML.includes('onerror=alert')")
9. Alternative Approaches
If the standard save-attachment action is sanitized by WordPress core before the plugin sees it (though this is unlikely given the CVE description), the plugin may have its own settings page for "Bulk Optimization" where it allows editing image metadata directly.
Alternative Payload:
If the attribute is rendered inside an existing alt="..." attribute:" onmouseover="alert(1)" style="position:fixed;top:0;left:0;width:100%;height:100%;"
This would break out of the attribute and execute on mouse hover over the image.
Summary
The Robin Image Optimizer plugin (<= 2.0.2) is vulnerable to Stored Cross-Site Scripting (XSS) via the 'Alternative Text' metadata field of images. Authenticated attackers with Author-level access or higher can inject malicious scripts into this field, which are then stored and executed when viewed by other users, particularly administrators, in the plugin's optimization logs or dashboard.
Exploit Outline
1. Authenticate to the WordPress dashboard as a user with Author-level privileges. 2. Identify a media attachment ID or upload a new image to the Media Library. 3. Send a POST request to `/wp-admin/admin-ajax.php` with the action `save-attachment` and the payload `<img src=x onerror=alert(document.domain)>` assigned to the `changes[alt_text__column]` parameter. 4. Ensure the request includes a valid nonce for the `save-attachment` action. 5. Trigger the vulnerability by navigating to the plugin's 'Bulk Optimization' page (`/wp-admin/admin.php?page=bulk_optimization-robin-image-optimizer`) where the plugin renders the image metadata without proper escaping, causing the script to execute in the administrator's browser context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.