CVE-2026-XXXXX — Persistent XSS in Zextras Carbonio WebMail — the Print function
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 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
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.
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
- Install Carbonio CE (tested on Ubuntu 24.04, carbonio-mails-ui v1.31.4)
- Send an email to a Carbonio user with the XSS payload in the sender display name (From field)
- Log in to Carbonio WebMail as the recipient
- Open the received message
- Open the actions menu (…) and select "Print"
- A new window opens with the print preview
- The JavaScript payload executes —
alert(document.domain)confirms code execution
PoC (Python)
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
- Vendor patch: Carbonio 26.03.0 changelog — Stored XSS in Print Email Feature
- Vendor: Zextras Carbonio
- CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
- OWASP: Cross Site Scripting (XSS)
- MITRE CVE: ID assignment in progress — the link will be added after publication.
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