Post SMTP <= 3.8.0 - Unauthenticated Stored Cross-Site Scripting via 'event_type'
Description
The Post SMTP – Complete Email Deliverability and SMTP Solution with Email Logs, Alerts, Backup SMTP & Mobile App plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘event_type’ parameter in all versions up to, and including, 3.8.0 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. The vulnerability is only exploitable when the Post SMTP Pro plugin is also installed and its Reporting and Tracking extension is enabled.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v3.9.0
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-3090 (Post SMTP Stored XSS) ## 1. Vulnerability Summary The **Post SMTP** plugin (specifically when the **Post SMTP Pro** and **Reporting and Tracking** extension are active) is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerabi…
Show full research plan
Exploitation Research Plan: CVE-2026-3090 (Post SMTP Stored XSS)
1. Vulnerability Summary
The Post SMTP plugin (specifically when the Post SMTP Pro and Reporting and Tracking extension are active) is vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS). The vulnerability exists because the plugin accepts the event_type parameter from unauthenticated tracking requests and stores it in the database (post_smtp_tracking table) without sufficient sanitization. This data is later rendered in the Post SMTP Dashboard (wp-admin/admin.php?page=postman) using Vue.js components that fail to escape the stored value, allowing an attacker to execute arbitrary JavaScript in the context of an authenticated administrator.
2. Attack Vector Analysis
- Endpoint: The public-facing site root with tracking query parameters.
- Action/Hook: Likely a hook on
initortemplate_redirectregistered by the Reporting and Tracking extension to log email opens/clicks. - Vulnerable Parameter:
event_type. - Authentication: None required (Unauthenticated).
- Preconditions:
- Post SMTP (<= 3.8.0) installed and active.
- Post SMTP Pro + Reporting and Tracking extension installed and enabled.
- Email tracking must be active in the plugin settings.
3. Code Flow
- Injection (Public):
- An unauthenticated request is sent to
/?ps-type=track&event_type=<payload>(inferred tracking URL pattern). - The Reporting extension processes this request and calls a database insertion method.
- The
event_typevalue is saved into the$wpdb->prefix . 'post_smtp_tracking'table.
- An unauthenticated request is sent to
- Retrieval (Admin Dashboard):
- An administrator visits
wp-admin/admin.php?page=postman. Postman/Dashboard/NewDashboard.phpenqueuesPostman/Dashboard/assets/js/app.js.- The Dashboard logic (registered via
psd/v1REST API inNewDashboard.php) fetches logs. - The REST API returns the raw
event_typefrom the database.
- An administrator visits
- Execution (Browser):
app.js(Vue components) receives the JSON response.- The data is rendered in the notification bar or event log (CSS classes like
.post-smtp-notification-contentinapp.csssuggest where this might appear). - Lack of output escaping in the Vue template results in JavaScript execution.
4. Nonce Acquisition Strategy
The injection phase is unauthenticated and typically does not require a nonce as it is intended for tracking pixels in email clients.
The verification phase (accessing the dashboard) uses a REST API nonce. If the automated agent needs to verify the presence of the payload via the REST API directly:
- Variable Name:
postSmtpNewDashboard(localized inPostman/Dashboard/NewDashboard.php). - Nonce Key:
nonce. - Extraction Method:
- Navigate to
wp-admin/admin.php?page=postman. - Use
browser_eval("window.postSmtpNewDashboard?.nonce").
- Navigate to
- REST Endpoint:
wp-json/psd/v1/get-failed-logs(as seen inapp.jsaxios calls) or a similar endpoint provided by the Pro version for reporting.
5. Exploitation Strategy
The goal is to inject a payload that will execute when the admin views the Post SMTP Dashboard.
Step 1: Injection Request
Send an HTTP GET request to the site root with the malicious event_type.
- URL:
http://[TARGET_URL]/?ps-type=track&event_type=XSS_INJECTED<img src=x onerror=alert(document.domain)> - Method:
GET - Tool:
http_request
Step 2: Triggering the XSS
The agent must simulate an administrator viewing the dashboard.
- Action: Login as admin and navigate to
/wp-admin/admin.php?page=postman. - Tool:
browser_navigate
Step 3: Capture Execution
Check for the alert or the presence of the injected DOM element.
6. Test Data Setup
- Install/Activate Post SMTP 3.8.0.
- Activate Pro/Reporting Extension: Since this is a Pro feature, the testing environment must have the
report-and-tracking-addon-premiumorpost-smtp-proplugin folder present to satisfy the check inPostman/Dashboard/NewDashboard.php:is_plugin_active( 'report-and-tracking-addon-premium/post-smtp-report-and-tracking.php' ) - Enable Tracking: Ensure
post_smtp_trackingtable is created. This usually happens on activation of the Pro addon. - Create a Dummy Log: (Optional) Send a test email via
wp-clito populate the tracking tables if the endpoint requires a validemail_id.
7. Expected Results
- The
http_requestto the tracking endpoint should return a200 OKor a transparent 1x1 pixel. - The
browser_navigateto the dashboard should result in a JavaScript execution (e.g.,alert(document.domain)). - Inspection of the HTML in the dashboard should show the unescaped payload within a notification or log list item.
8. Verification Steps
- Check Database: Use
wp db queryto verify the payload is stored:wp db query "SELECT * FROM wp_post_smtp_tracking WHERE event_type LIKE '%XSS_INJECTED%';" - Check REST API Response: Use the
http_requesttool (authenticated) to call the dashboard API and see the unescaped payload in the JSON:# Get nonce first via browser_eval # Then call API GET /wp-json/psd/v1/get-failed-logs Header: X-WP-Nonce: [NONCE]
9. Alternative Approaches
If /?ps-type=track fails:
- Try
/?ps-event=track&event_type=... - Try
POSTto the same endpoint. - Search the plugin source (if available) for
$_GET['event_type']or$_POST['event_type']to find the exact hook handling the tracking data. - Payload Variation: Use a payload that breaks out of common Vue attributes if it's rendered inside a directive:
{{8*8}}or"><script>alert(1)</script>.
Summary
The Post SMTP plugin (when the Pro Reporting and Tracking extension is active) allows unauthenticated attackers to store malicious JavaScript via the 'event_type' parameter in tracking requests. This script executes in the context of an administrator's browser when they access the plugin's dashboard.
Vulnerable Code
// Postman/Dashboard/NewDashboard.php - Line 89 // The code retrieves event_type from the tracking table which is populated by external requests. public function opened_email_count( $count, $args ) { $current_time = $args['current_time']; $filter = $args['filter']; global $wpdb; $sql = 'SELECT COUNT( * ) FROM %i WHERE event_type = "open-email" AND time <= %d AND time >= %d'; $sql = $wpdb->prepare( $sql, $wpdb->prefix . 'post_smtp_tracking', $current_time, $filter ); return $wpdb->get_var( $sql ); } --- // Postman/Dashboard/assets/js/app.js // The Vue components render event logs and notifications fetched from the REST API. // The data (including event_type) is rendered without proper output escaping, // allowing for script execution when an admin views the dashboard notification bar. // Relevant CSS selectors: .post-smtp-notification-content, .post-smtp-notification-title
Security Fix
@@ -1,34 +1,43 @@ +/*!***************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js!./src/app.css ***! + \***************************************************************/ @import url(https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap); +/*!**************************************************************************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./src/components/post-smtp-app-wrapper.vue?vue&type=style&index=0&id=7c6051c6&scoped=true&lang=css ***! + \**************************************************************************************************************************************************************************************************************************************************************************/ -.post-smtp__wrapper[data-v-3112b8ca] { +.post-smtp__wrapper[data-v-7c6051c6] { background: #F9FBFF; } -.mr-25[data-v-3112b8ca] { +.mr-25[data-v-7c6051c6] { margin-right: 25px; } -.container[data-v-3112b8ca] { +.container[data-v-7c6051c6] { padding: 0 51px; } -.mt-32[data-v-3112b8ca] { +.mt-32[data-v-7c6051c6] { margin-top: 32px; } -.app-wrapper[data-v-3112b8ca] { +.app-wrapper[data-v-7c6051c6] { width: calc( 100% - 276px - 25px ); } -.app-sidebar[data-v-3112b8ca] { +.app-sidebar[data-v-7c6051c6] { width: 276px; } -.float-left[data-v-3112b8ca] { +.float-left[data-v-7c6051c6] { float: left; } -.clearfix[data-v-3112b8ca]::after { +.clearfix[data-v-7c6051c6]::after { clear: both; content: ""; display: table; }
Exploit Outline
The exploit target is the unauthenticated tracking endpoint used by the Post SMTP Pro 'Reporting and Tracking' extension. An attacker sends a GET request to the site root with specific tracking parameters: `/?ps-type=track&event_type=<img src=x onerror=alert(1)>`. The plugin's tracking logic (running on `init` or `template_redirect`) saves this malicious `event_type` into the `post_smtp_tracking` database table without sanitization. When an administrator later logs in and visits the Post SMTP Dashboard (`wp-admin/admin.php?page=postman`), the dashboard's Vue.js frontend fetches the tracking logs via a REST API call to `wp-json/psd/v1/get-failed-logs`. The frontend then renders the raw payload in a notification bar or event list, triggering the stored script.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.