Status: Patched
This vulnerability has been verified as resolved and deployed.
mmctl terminal escape injection via unsanitized server-controlled output (CVE-2026-3108)
Summary
mmctl rendered user-controlled Mattermost content to administrator terminals without stripping ANSI, OSC, DCS, or other control sequences
Mattermost's mmctl plain-text output path accumulated values from API responses and templates in printer.Lines, then wrote each line directly to stdout in Printer.linesToBytes. The report-posts command also bypassed the printer and wrote post.Message directly with fmt.Fprintf(os.Stdout, ...). Because post messages and many other displayed fields can be controlled by ordinary users on the server being administered, a malicious value containing ANSI CSI sequences or OSC sequences could be replayed into an administrator's terminal when they inspected data with mmctl.
The root cause was a missing terminal-output trust boundary: the CLI treated server data as display-safe text. The fix added printer.SanitizeForTerminal, applied it to the central plain-output sink in linesToBytes, and separately sanitized the direct report command message print. The original fix is PR #35191 / commit 22e4e9c171dcf9b447a56c7d9a45e5714fb24536; release-line backports include #35208, #35276, #35334, and #35335.
CVSS Score
Vulnerability Location
Source-to-Sink Analysis
The administrator runs mmctl report posts, which fetches post objects from the Mattermost API and passes every returned post into printReportPost. The post.Message field is user-controlled content stored on the server.
Before the fix, report output wrote post.Message directly to stdout. The patched code applies printer.SanitizeForTerminal before rendering the message.
Most mmctl commands render API-derived values through templates and append the rendered string into printer.Lines.
The central plain-text sink now converts each line to a string and strips terminal control sequences before writing to the output buffer.
SanitizeForTerminal removes ANSI CSI, OSC, DCS, APC/PM, single-character escape sequences, and remaining control characters except tab, newline, and carriage return.
Impact Analysis
Critical Impact
The bug crosses the trust boundary between untrusted server data and the administrator's local terminal. Depending on terminal behavior, payloads can alter terminal state, hide or rewrite displayed output, set misleading prompts or window titles, or abuse OSC features such as clipboard writes. This is not server-side code execution, but it is a high-impact operator-side terminal injection primitive against privileged users.
Attack Surface
Administrators or operators running mmctl against a Mattermost instance containing attacker-controlled content, especially commands that print post messages, user fields, channel names, webhook data, or other server-originated strings in plain format.
Preconditions
The attacker must be able to place content that later appears in mmctl output. A privileged user must run an affected mmctl command in a terminal that interprets escape sequences. JSON output is less exposed because JSON encoding escapes control bytes, while plain output was vulnerable.
Proof of Concept
Environment Setup
Use a vulnerable Mattermost build before PR #35191 and a terminal that interprets ANSI/OSC sequences. Configure mmctl for an administrator account.
Target Configuration
Any server where an ordinary user can create a post that an administrator later reviews with mmctl report posts or another plain-output mmctl command.
Exploit Delivery
Create a post containing terminal control bytes such as CSI screen-clear sequences or an OSC clipboard sequence. Then run mmctl report posts as an administrator and include the malicious post in the report results.
Outcome
The fix prevents terminal interpretation by sanitizing both the central printer path and the direct report-post message output.
Expected Response:
On vulnerable builds, the terminal receives the raw escape bytes from post.Message or from printer.Lines. On fixed builds, the same output is rendered with the escape/control sequences removed.
