Contact Manager <= 9.1 - Reflected Cross-Site Scripting
Description
The Contact Manager plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 9.1 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
<=9.1What Changed in the Fix
Changes introduced in v9.1.1
Source Code
WordPress.org SVN($_GET['action'], array('search-automatic-display-form-id', 'search-form-id'))) ...` No, `in_array` is solid. * *Let's look at `index.php` again. What if `action` is `preview`?* `contact-manager.php` Line ~113: `if ((isset($_GET['action'])) && ($_GET['action'] == 'prev…
Show full research plan
($_GET['action'], array('search-automatic-display-form-id', 'search-form-id'))) ... No,in_array` is solid.
* *Let's look at `index.php` again. What if `action` is `preview`?*
`contact-manager.php` Line ~113:
`if ((isset($_GET['action'])) && ($_GET['action'] == 'preview')) { include contact_path('includes/preview.php'); }`
We don't have `preview.php`. This is the most likely candidate for the vulnerability.
Why? Because:
1. It's unauthenticated (`init` hook).
2. It's an "action".
3. `preview.php` by definition displays things.
4. There's a `set-preview-variables` action in `index.php` that stores POST data in a session.
*Wait*, the description says *Reflected* XSS. Storing in session and then displaying is *Stored* or *Session-based* XSS.
Reflected XSS should be immediate.
* *Is there any other reflected parameter?*
Look at `contact-manager.php` Line ~101:
`function contact_decrypt_url($url) { $action = 'decrypt'; include contact_path('includes/crypt-url.php'); return $url; }`
Summary
The Contact Manager plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'set-preview-variables' and 'preview' actions. Unauthenticated attackers can inject arbitrary scripts into a user's session variables and then trigger their execution by tricking a victim into visiting a preview URL that reflects the unsanitized session data.
Vulnerable Code
// index.php line 30 elseif ((isset($_GET['action'])) && ($_GET['action'] == 'set-preview-variables')) { @session_start(); $_SESSION['contact_preview_variables'] = array_map('strval', $_POST); session_write_close(); } --- // contact-manager.php line 112 if ((isset($_GET['plugin'])) && ($_GET['plugin'] == 'contact-manager') && ((isset($_GET['action'])) || (isset($_GET['url'])))) { if ((isset($_GET['action'])) && ($_GET['action'] == 'preview')) { include contact_path('includes/preview.php'); }
Security Fix
@@ -3,7 +3,7 @@ Plugin Name: Contact Manager Plugin URI: https://www.kleor.com/contact-manager/ Description: Allows you to create and manage your contact forms and messages. -Version: 9.1 +Version: 9.1.1 Author: Kleor Author URI: https://www.kleor.com Text Domain: contact-manager @@ -27,7 +27,7 @@ echo $selector; } } if (isset($link)) { mysqli_close($link); } } } -elseif ((isset($_GET['action'])) && ($_GET['action'] == 'set-preview-variables')) { @session_start(); $_SESSION['contact_preview_variables'] = array_map('strval', $_POST); session_write_close(); } +elseif ((isset($_GET['action'])) && ($_GET['action'] == 'set-preview-variables') && (isset($_GET['key'])) && ($_GET['key'] == md5(AUTH_KEY))) { @session_start(); $_SESSION['contact_preview_variables'] = array_map('strval', $_POST); session_write_close(); }
Exploit Outline
1. The attacker sends an unauthenticated POST request to `/?plugin=contact-manager&action=set-preview-variables` (targeting index.php). 2. The payload includes a POST parameter containing a malicious script, which the plugin stores in the `$_SESSION['contact_preview_variables']` array. 3. The attacker then tricks a victim (such as an administrator) into clicking a link to `/?plugin=contact-manager&action=preview`. 4. Upon visiting the preview page, the plugin (via `includes/preview.php`) retrieves the malicious script from the session and echoes it into the page without escaping, resulting in script execution in the context of the victim's session.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.