Back to blog

CVE-2026-XXXXX — Persistent XSS in Zextras Carbonio WebMail — the Print function

August 4, 2026 Grzegorz Tworek 7 min read

How, during an infrastructure penetration test, I discovered a Persistent XSS vulnerability in the message Print function of Zextras Carbonio WebMail — participant display names are inserted into the print template without escaping, and the print window has no CSP headers.

Persistent XSS in Zextras Carbonio WebMail — the Print function

Persistent Cross-Site Scripting in the Print function of Zextras Carbonio WebMail (carbonio-mails-ui)

Zextras Carbonio is an open-source email and collaboration platform (email, calendar, files, video conferencing), developed as an alternative to Zimbra and deployed in public administration and enterprises. The carbonio-mails-ui component provides the web-based mail interface.

How it was found

I originally identified this vulnerability during an authorized infrastructure penetration test for a client running an earlier, commercial version of Carbonio. To confirm the issue on a clean, publicly available environment, I then reproduced it on a fresh Carbonio Community Edition install downloaded directly from the vendor (carbonio-mails-ui v1.31.4, carbonio-appserver 4.4.4, Ubuntu 24.04 LTS).

This means the issue affects both the Community Edition and the commercial versions — not only the latest release. The report was submitted to the Zextras security team under responsible disclosure.

Vulnerability details

CVE ID CVE-2026-XXXXX — assignment in progress (MITRE CNA-LR)
Type CWE-79: Stored (Persistent) Cross-Site Scripting
Product Zextras Carbonio WebMail (carbonio-mails-ui)
Tested version v1.31.4 (Carbonio CE) and earlier commercial versions
Component Print function (email print preview)
Attack vector Network (delivered via email)
User interaction Required (one click: Print)
CVSS 3.1 8.1 HIGH
CVSS 3.1 vector AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Status Fixed by the vendor in Carbonio 26.03.0

Technical analysis

Root cause

The Print function builds an HTML page containing email metadata. Participant display names (fullName for the From, To, CC, BCC, Reply-To fields) are interpolated directly into the print template without HTML entity encoding. Notably, the Subject field in the same template is properly escaped using lodash _.escape() — indicating the developers were aware of the injection risk but failed to apply the same protection to the participant name fields.

In addition, the print window is opened via window.open("","_blank"), which creates an about:blank document rendered with document.write() — with no HTTP response headers and therefore no Content-Security-Policy. The absence of CSP means unrestricted execution of the injected JavaScript.

Key observation: selective escaping is a common anti-pattern — it takes only one field left out of the template for the entire protection mechanism to fail. Output encoding must be applied consistently to every user-controlled value, no matter how "harmless" a given field appears.

Payload

"<img src=x onerror=alert(document.domain)>" <[email protected]>

The payload is placed in the sender display name (From display name). In the normal message view it is safely rendered as text — only using the Print function triggers execution in the context of the victim's authenticated session.

Zextras Carbonio Print XSS PoC — alert showing document.domain in the print window

Proof of Concept — the print window renders the payload from the From field. The alert shows document.domain, confirming JavaScript execution in the Carbonio application origin

Steps to reproduce

  1. Install Carbonio CE (tested on Ubuntu 24.04, carbonio-mails-ui v1.31.4)
  2. Send an email to a Carbonio user with the XSS payload in the sender display name (From field)
  3. Log in to Carbonio WebMail as the recipient
  4. Open the received message
  5. Open the actions menu (…) and select "Print"
  6. A new window opens with the print preview
  7. The JavaScript payload executesalert(document.domain) confirms code execution

PoC (Python)

import smtplib from email.mime.text import MIMEText from email.utils import formataddr msg = MIMEText('<p>Please print this message.</p>', 'html') msg['From'] = formataddr(('<img src=x onerror=alert(document.domain)>', '[email protected]')) msg['To'] = 'victim@carbonio-instance' msg['Subject'] = 'Stored XSS via Print' with smtplib.SMTP('localhost', 25) as s: s.sendmail('[email protected]', ['victim@carbonio-instance'], msg.as_string())

Impact

Session cookies are protected with the HttpOnly flag and cannot be read via document.cookie. However, the payload executes in the same origin as the Carbonio application — the browser automatically attaches cookies to same-origin requests (fetch, XMLHttpRequest), giving the attacker full access to the Carbonio SOAP API without knowing the cookie values.

Reading mail

Reading all of the victim's messages via SearchRequest / GetMsgRequest — full access to the mailbox.

Sending as the victim

Sending messages on behalf of the victim (SendMsgRequest) and modifying account settings.

Silent mail interception

Creating forwarding rules to silently exfiltrate all incoming correspondence.

Propagation and lateral movement

Spreading the attack to contacts (worm behaviour) and accessing the Files, Contacts and Calendar modules that share the same origin.

Suggested remediation

The recommendation provided to the vendor:

  • HTML entity encoding of participant display names in the print template — using the same _.escape() function (lodash) already applied to the Subject field.
  • Adding a Content-Security-Policy header / meta tag to the print HTML template to block inline script execution as a defense-in-depth measure.

Disclosure Timeline

Date Event
2026-03-16 Vulnerability discovered and reproduced on Carbonio CE v1.31.4
2026-03-17 Reported to the Zextras security team ([email protected]) with a full report, PoC and screenshots
2026-03 Vulnerability confirmed by Zextras; fix in progress (stated target ~60 days)
2026-07-28 Vendor patch released — Carbonio 26.03.0 (changelog: "Stored XSS in Print Email Feature", crediting Grzegorz Tworek (sec4check))
2026-08 CVE ID request submitted (MITRE CNA-LR)

Takeaways

1. Output encoding must be consistent

Correctly escaping one field (Subject) while omitting others (participant names) in the same template is a classic mistake. Every user-controlled value requires output encoding — no exceptions.

2. Unusual rendering contexts matter just as much

The "Print" function looks secondary, yet it renders user data in an about:blank window with no CSP. During pentesting it pays to test every data-rendering path — not just the main application view.

3. "Metadata" fields can be an attack vector

The sender display name is fully attacker-controlled and reaches many views. It is a prime candidate for stored XSS if even one of those views skips sanitisation.

References

Looking for vulnerabilities in your application?

Professional penetration testing of web applications, APIs and infrastructure. I find vulnerabilities before attackers do — from simple XSS to complex chain attacks.

Book a free consultation
Back to blog