CVE-2026-1043

PostmarkApp Email Integrator <= 2.4 - Authenticated (Administrator+) Stored Cross-Site Scripting via Plugin Settings

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
4.4
CVSS Score
4.4
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The PostmarkApp Email Integrator plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin settings in versions up to, and including, 2.4. This is due to insufficient input sanitization and output escaping on the pma_api_key and pma_sender_address parameters. This makes it possible for authenticated attackers, with Administrator-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses the settings page.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
High
Privileges Required
High
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.4
PublishedFebruary 18, 2026
Last updatedApril 15, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1043 ## 1. Vulnerability Summary The **PostmarkApp Email Integrator** plugin (versions <= 2.4) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The plugin fails to sanitize or escape user-controlled settings—specifically the `pma_api_key` and `pma_sende…

Show full research plan

Exploitation Research Plan: CVE-2026-1043

1. Vulnerability Summary

The PostmarkApp Email Integrator plugin (versions <= 2.4) is vulnerable to Stored Cross-Site Scripting (XSS). The plugin fails to sanitize or escape user-controlled settings—specifically the pma_api_key and pma_sender_address parameters—before saving them to the database and subsequently rendering them in the WordPress administration dashboard.

While the vulnerability requires Administrator-level privileges to exploit (PR:H), it poses a significant risk in environments where unfiltered_html is disabled or in Multisite configurations where a Site Admin (not Super Admin) can use this to target a Super Admin.

2. Attack Vector Analysis

  • Vulnerable Parameters: pma_api_key, pma_sender_address
  • Entry Point: Plugin settings page, likely found at /wp-admin/options-general.php?page=postmarkapp-email-integrator (inferred) or /wp-admin/admin.php?page=pma-settings (inferred).
  • Authentication: Required (Administrator or above).
  • Vulnerability Mechanism: Improper storage (missing sanitize_text_field) and improper output (missing esc_attr or esc_html) in the admin settings view.

3. Code Flow (Inferred)

  1. Submission Phase:
    • An administrator navigates to the plugin settings page.
    • A POST request is sent to options.php (if using Settings API) or the plugin's own admin page handler.
    • The plugin processes the input using update_option('pma_api_key', $_POST['pma_api_key']) without applying sanitization functions.
  2. Execution Phase:
    • An administrator (the attacker or a victim) views the settings page.
    • The plugin retrieves the value: $api_key = get_option('pma_api_key');.
    • The value is echoed directly into an HTML input attribute or a table cell: echo '<input type="text" name="pma_api_key" value="' . $api_key . '">';.
    • The browser interprets the injected script, executing it in the context of the administrator's session.

4. Nonce Acquisition Strategy

The plugin likely uses the standard WordPress Settings API or a custom form with a nonce check (check_admin_referer). To exploit this via the http_request tool, we must first extract the valid nonce from the settings page.

  1. Identify the Settings Page: Navigate to the admin dashboard and find the "Postmark" or "Email Integrator" settings link.
  2. Navigate and Extract:
    • Use browser_navigate to load the settings page.
    • Use browser_eval to locate the nonce field.
    • Common Settings API nonce name: _wpnonce.
    • Plugin-specific nonce keys might be localized in a global JS object or hidden in the form.

JavaScript to extract nonce:

// If standard Settings API form:
document.querySelector('input[name="_wpnonce"]')?.value;

// If custom form (check page source for nonce field names):
document.querySelector('input[name*="nonce"]')?.value;

5. Exploitation Strategy

The goal is to store a payload that executes alert(document.domain) when the settings page is viewed.

Step 1: Discover the Form Structure

  1. Navigate to the settings page as an Administrator.
  2. Inspect the HTML to identify the exact name attributes for the API key and Sender Address fields. Let's assume they are pma_api_key and pma_sender_address based on the CVE description.
  3. Identify the action attribute of the form (likely options.php).

Step 2: Perform the Injection

Send a POST request to update the options.

  • URL: http://[target]/wp-admin/options.php (if using Settings API) or the current page URL.
  • Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • option_page: (e.g., postmark_settings_group)
    • action: update
    • _wpnonce: [EXTRACTED_NONCE]
    • pma_api_key: "><script>alert(document.domain)</script>
    • pma_sender_address: "><img src=x onerror=alert(1)>

Step 3: Trigger the XSS

  1. Navigate to the plugin settings page: browser_navigate("http://[target]/wp-admin/options-general.php?page=postmarkapp-email-integrator").
  2. The browser will render the unescaped values in the input fields, breaking out of the value attribute and executing the scripts.

6. Test Data Setup

  1. Active Plugin: Ensure postmarkapp-email-integrator is installed and activated.
  2. User Role: Use an existing Administrator account.
  3. Multisite (Optional): If testing for privilege escalation, ensure DISALLOW_UNFILTERED_HTML is set to true in wp-config.php to verify that the plugin's lack of sanitization bypasses the WordPress core's intent.

7. Expected Results

  • After the POST request, the WordPress site should return a 302 Redirect back to the settings page with a settings-updated=true parameter.
  • Upon visiting the settings page, an alert box showing the domain name should appear (verified via browser_eval to check for the presence of the script or the result of the alert).
  • The HTML source of the settings page should show:
    <input ... value=""><script>alert(document.domain)</script>">

8. Verification Steps (WP-CLI)

Confirm the payload is stored in the database without sanitization:

wp option get pma_api_key
# Expected output: "><script>alert(document.domain)</script>

wp option get pma_sender_address
# Expected output: "><img src=x onerror=alert(1)>

9. Alternative Approaches

If the plugin does not use the Settings API (options.php), it may handle the POST request via the admin_init hook or within the menu callback function.

  • Alternative Sink: Check if the pma_sender_address is used in email headers sent by the plugin. If so, this could lead to Header Injection, but the primary CVE report focuses on the XSS in the settings page.
  • Bypassing Nonces: If the plugin checks nonces incorrectly (e.g., using check_admin_referer with a fixed string instead of a dynamic nonce), the exploit could be performed via CSRF.
  • Blind XSS: If the settings are reflected on a different admin page (e.g., a dashboard widget), check those pages as well.
Research Findings
Static analysis — not yet PoC-verified

Summary

The PostmarkApp Email Integrator plugin for WordPress (versions up to 2.4) is vulnerable to Stored Cross-Site Scripting due to improper input sanitization and output escaping of the 'pma_api_key' and 'pma_sender_address' parameters. Authenticated administrators can inject malicious scripts into these settings, which execute in the browser of any user accessing the plugin's configuration page.

Vulnerable Code

// Inferred vulnerability in settings storage (likely in an admin_init hook or settings form handler)
update_option('pma_api_key', $_POST['pma_api_key']);
update_option('pma_sender_address', $_POST['pma_sender_address']);

---

// Inferred vulnerability in settings display (admin settings page template)
$api_key = get_option('pma_api_key');
$sender_address = get_option('pma_sender_address');
?>
<input type="text" name="pma_api_key" value="<?php echo $api_key; ?>" />
<input type="text" name="pma_sender_address" value="<?php echo $sender_address; ?>" />

Security Fix

--- a/postmarkapp-email-integrator.php
+++ b/postmarkapp-email-integrator.php
@@ -10,8 +10,8 @@
-update_option('pma_api_key', $_POST['pma_api_key']);
-update_option('pma_sender_address', $_POST['pma_sender_address']);
+update_option('pma_api_key', sanitize_text_field($_POST['pma_api_key']));
+update_option('pma_sender_address', sanitize_email($_POST['pma_sender_address']));
 
@@ -25,2 +25,2 @@
- <input type="text" name="pma_api_key" value="<?php echo $api_key; ?>" />
- <input type="text" name="pma_sender_address" value="<?php echo $sender_address; ?>" />
+ <input type="text" name="pma_api_key" value="<?php echo esc_attr($api_key); ?>" />
+ <input type="text" name="pma_sender_address" value="<?php echo esc_attr($sender_address); ?>" />

Exploit Outline

1. Authenticate to the WordPress dashboard as a user with Administrator privileges. 2. Navigate to the PostmarkApp Email Integrator settings page (likely located under Settings > PostmarkApp). 3. Capture the nonce required for settings updates (e.g., from the '_wpnonce' hidden input field). 4. Send a POST request to /wp-admin/options.php (if using the Settings API) or the plugin's own settings handler. 5. Include a payload in the 'pma_api_key' or 'pma_sender_address' parameters designed to break out of an HTML attribute, such as: "><script>alert(document.domain)</script>. 6. The script will be stored in the 'wp_options' table. To trigger the execution, any administrator must simply view the plugin settings page, where the payload will be echoed without sanitization into the input's 'value' attribute.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.