Easy Image Gallery <= 1.5.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via Gallery Shortcode Post Meta
Description
The Easy Image Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the Gallery shortcode post meta field in all versions up to, and including, 1.5.3. This is due to insufficient input sanitization and output escaping on user-supplied gallery shortcode values. 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
<=1.5.3# Exploitation Research Plan: CVE-2024-4766 (Easy Image Gallery <= 1.5.3) ## 1. Vulnerability Summary The **Easy Image Gallery** plugin for WordPress is vulnerable to **Stored Cross-Site Scripting (XSS)** in versions up to 1.5.3. The vulnerability exists because the plugin fails to sanitize and esc…
Show full research plan
Exploitation Research Plan: CVE-2024-4766 (Easy Image Gallery <= 1.5.3)
1. Vulnerability Summary
The Easy Image Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) in versions up to 1.5.3. The vulnerability exists because the plugin fails to sanitize and escape user-supplied input stored in post meta fields associated with its gallery functionality. Specifically, when a user with Contributor-level permissions or higher saves a post, they can inject malicious scripts into gallery-related metadata. These scripts are then executed in the context of any user (including Administrators) who views the post on the frontend or edits it in the backend.
2. Attack Vector Analysis
- Endpoint:
wp-admin/post.php(Standard WordPress post update handler). - Action:
editpost. - Vulnerable Parameters (inferred):
easy_image_gallery_link_target,easy_image_gallery_custom_link, or internal meta fields used to store attributes for the[easy_image_gallery]shortcode. - Authentication: Required (Contributor-level or higher).
- Preconditions: The plugin must be active, and a post containing (or intended to contain) a gallery must be edited.
3. Code Flow (Inferred)
- Entry Point (Admin): A user with
edit_postscapability (Contributor+) visits the post editor. - Meta Box Registration: The plugin registers a meta box using
add_meta_box(likely inincludes/admin/metabox.phporeasy-image-gallery.php). - Data Processing (Save): When the post is saved, a hook for
save_post(e.g.,easy_image_gallery_save_post_meta) captures input from$_POST. - Insecure Storage: The code likely uses
update_post_meta( $post_id, '_easy_image_gallery_...', $_POST['...'] )without callingsanitize_text_field()oresc_attr(). - Frontend Sink: When the post is rendered, the plugin retrieves meta via
get_post_meta(). - Unescaped Output: The values are echoed directly into the HTML (e.g., inside an
<a>tag'stargetorhrefattribute) in the frontend gallery template or via the[easy_image_gallery]shortcode handler.
4. Nonce Acquisition Strategy
This is an authenticated exploit targeting the WordPress admin dashboard. The agent must obtain a valid WordPress core nonce for the editpost action.
- Log in as a Contributor user.
- Navigate to
wp-admin/post-new.phpto initiate a new post. - Extract Data: Use
browser_evalto extract thepost_IDand the_wpnoncefrom the page source.post_IDis found in the hidden inputname="post_ID"._wpnonceis found in the hidden inputname="_wpnonce".
- Identify Meta Fields: Inspect the Easy Image Gallery meta box. Based on plugin structure, look for fields with names like
easy_image_gallery_link_target.
5. Exploitation Strategy
- Authentication: Login as a Contributor.
- Initial Post Creation:
- Navigate to
wp-admin/post-new.php. - Capture
post_IDand_wpnonce.
- Navigate to
- Inject Payload:
- Perform an
http_request(POST) towp-admin/post.php. - Payload:
"><script>alert(document.domain)</script> - Target Parameter:
easy_image_gallery_link_target(common in this plugin for XSS). - Request Body:
action=editpost post_ID=[CAPTURED_ID] _wpnonce=[CAPTURED_NONCE] post_title=Gallery Test content=[easy_image_gallery] easy_image_gallery_link_target="><script>alert(document.domain)</script>
- Perform an
- Trigger Execution: Navigate to the frontend URL of the created post:
/?p=[POST_ID].
6. Test Data Setup
- User: Create a user with the
Contributorrole. - Plugin Configuration: Ensure "Easy Image Gallery" is active.
- Post Content: A post must contain the shortcode
[easy_image_gallery]to trigger the rendering logic that fetches the malicious meta.
7. Expected Results
- The POST request should return a
302 Redirectback to the post edit page (indicating success). - When navigating to the frontend post URL, an alert box showing the document domain should appear.
- Inspection of the HTML source should show the script tag injected into the gallery's container or link attributes.
8. Verification Steps
- WP-CLI Check: Verify the meta was saved without sanitization:
wp post meta get [POST_ID] easy_image_gallery_link_target - Frontend Check: Use
browser_navigateto the post and check for the presence of the script in the DOM:// browser_eval document.body.innerHTML.includes('<script>alert(document.domain)</script>')
9. Alternative Approaches
If easy_image_gallery_link_target is not the correct parameter:
- Check for Hidden Meta: Some versions store gallery image IDs in
_easy_image_gallery. Try injecting into parameters that might be used as "Custom Link" attributes for individual images. - Shortcode Attributes: If the plugin allows custom attributes in the shortcode that are saved to meta (e.g., through a "Settings" tab in the meta box), target those fields.
- Injected Payload Variation: If the sink is inside an attribute, use:
x" onmouseover="alert(1)". If inside a URL, use:javascript:alert(1).
Summary
The Easy Image Gallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the gallery link target and other meta fields. Authenticated attackers with Contributor-level access or higher can inject malicious scripts into post meta, which are then rendered without proper escaping when the gallery shortcode is displayed on the frontend.
Vulnerable Code
// In includes/admin/metabox.php (inferred based on plugin structure) function easy_image_gallery_save_post_meta( $post_id ) { if ( isset( $_POST['easy_image_gallery_link_target'] ) ) { // Vulnerable: Metadata is updated without sanitization update_post_meta( $post_id, '_easy_image_gallery_link_target', $_POST['easy_image_gallery_link_target'] ); } } --- // In includes/shortcode.php (inferred rendering logic) $link_target = get_post_meta( get_the_ID(), '_easy_image_gallery_link_target', true ); // Vulnerable: Output is echoed without escaping within an attribute context echo '<a href="#" target="' . $link_target . '">...</a>';
Security Fix
@@ -10,7 +10,7 @@ function easy_image_gallery_save_post_meta( $post_id ) { if ( isset( $_POST['easy_image_gallery_link_target'] ) ) { - update_post_meta( $post_id, '_easy_image_gallery_link_target', $_POST['easy_image_gallery_link_target'] ); + update_post_meta( $post_id, '_easy_image_gallery_link_target', sanitize_text_field( $_POST['easy_image_gallery_link_target'] ) ); } } @@ -50,5 +50,5 @@ $link_target = get_post_meta( get_the_ID(), '_easy_image_gallery_link_target', true ); -echo '<a href="#" target="' . $link_target . '">...</a>'; +echo '<a href="#" target="' . esc_attr( $link_target ) . '">...</a>';
Exploit Outline
1. Log in as a user with Contributor-level access or higher. 2. Navigate to 'Posts' -> 'Add New' or edit an existing post. 3. Locate the 'Easy Image Gallery' meta box. If the 'Link Target' field is not visible, use a proxy tool or browser console to submit a POST request to 'wp-admin/post.php' with 'action=editpost'. 4. Include the parameter 'easy_image_gallery_link_target' (or the equivalent internal meta field) set to a malicious payload like '"><script>alert(document.domain)</script>'. 5. Add the '[easy_image_gallery]' shortcode to the post content and save/update the post. 6. View the published post on the frontend as any user. The script will execute because the plugin fails to escape the 'target' attribute when rendering the gallery links.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.