Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessDeliver crafted color-control OSC bytes to terminal
-
Deliverykitty color_control() echoes malicious field name into reply
-
Exploitwrite_escape_code_to_child() injects reply into pty master
-
Executionshell reads reply as typed input plus newline
-
ImpactExecute attacker command as the user
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Input neutralization, injection prevention
|
| Exploitation Conditions | Requires kitty version 0.47.3 up to (not including) 0.49.0. The attacker must get crafted bytes written to the terminal that the user renders - e.g. displaying a malicious file, command output, log, SSH banner, or web response containing the color-control OSC query whose field name encodes a shell command using only printable ASCII (excluding ';' and '=' which are consumed as delimiters). A newline to submit the injected command is obtainable via the ssh kitten path (handle_remote_ssh/get_ssh_data emits leading newline bytes before credential checks). Limiting factors: local attack vector (AV:L) and required user interaction (UI:P) - the victim must actually display attacker-controlled output in an affected kitty build; command runs only with the user's own shell privileges, and default configurations are affected once malicious output is rendered. |
| Impact | This is a genuine high-priority terminal-emulator RCE, but the CVSS 4.0 score of 9.3 slightly overstates real-world reach because the input CVSS vector itself is AV:L/UI:P - exploitation is local and requires user interaction, not a remote unauthenticated one-click. The mechanism is well documented and corroborated by the vendor fix commits (03fbdad and 57bb144) and release v0.49.0: kitty's color_control() echoed an unrecognised query field name verbatim into an OSC reply, and write_escape_code_to_child() wrote that reply back into the pseudoterminal master where the shell reads it as if typed by the user, enabling command injection (CWE-74). Notably this is a regression/bypass of the CVE-2026-54057 fix: the 0.47.3 mitigation reduced the echoed payload to printable ASCII and consumes ';' and '=' as delimiters, but every other printable character survives, which is sufficient to compose a shell command, and a newline needed to submit the command is sourced from handle_remote_ssh()/get_ssh_data() before credential checks. No EPSS score, no CISA KEV listing, and no confirmed public exploit are present in the provided data, so this is not evidence of active exploitation; there is a CNA/third-party writeup (secur0.com) that may contain technical detail but POC status is unconfirmed. Net: treat as a real priority for kitty users (patch to 0.49.0) but not an emergency mass-exploitation event on current evidence. |
| Exploit ScenarioDerived | A user running kitty (0.47.3-0.48.x) views attacker-controlled output - e.g. cats a malicious file, curls a hostile URL, reads a crafted log, or connects where attacker bytes reach the terminal - that contains a crafted color-control OSC query with a field name encoding a shell command. kitty echoes the field name back into the pty master, and because that reply is indistinguishable from typed input (with a newline obtainable via the ssh kitten path), the user's shell executes the attacker's command at the user's privilege level. No public exploit code is identified in the provided data, though a CNA writeup exists. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 25, 2026
Command injection in the kitty terminal emulator (versions 0.47.3 through 0.48.x) lets any program that can get output rendered on screen - a file shown with cat, a log line, command output, an SSH banner, or a web response - make kitty write attacker-composed printable ASCII back into the pseudoterminal, where the user's shell treats it as typed input and executes it with the user's privileges. The root cause is that the OSC 21 colour-control handler echoed unrecognised field names verbatim into its reply, and the 0.47.3 restriction (introduced as the fix for CVE-2026-54057) to printable ASCII excluding ';' and '=' still left enough characters to compose a shell command; the newline needed to submit that command is obtainable through the ssh kitten path. Exploitation is local (AV:L) and requires the victim to display attacker-controlled bytes (UI:P), no privileges are required, and no public exploit code has been identified in the available intelligence at time of analysis. The 9.3 CVSS 4.0 base score overstates real-world reach, since this is not a remote, unauthenticated, one-click compromise; the vendor-released patch is kitty 0.49.0.
RemediationAI
Primary fix: upgrade kitty to 0.49.0 or later (release tag v0.49.0), which incorporates commits 03fbdad855490470233954bc810e517027e5e640 and 57bb144d96c0f9d48a2b0a6d43c9a23d2a091cbf and changes the OSC 21 colour-control reply so unknown field names are returned as 'unknown=<base64>' rather than echoed verbatim; vendor-released patch: 0.49.0. Do not treat a downgrade as a workaround: 0.47.3 was itself the fix for CVE-2026-54057 (https://www.cve.org/CVERecord?id=CVE-2026-54057), so reverting below it simply re-exposes the earlier escape-code issue. Because the complete fix lives in the terminal rather than in a configuration switch, the practical interim measures are behavioural: avoid rendering untrusted output (log files, downloads, mail, web responses, banners) inside an affected kitty window, and in particular avoid the ssh kitten path against untrusted hosts, since handle_remote_ssh()/get_ssh_data() supplies the leading newline that submits the injected command before credentials are validated; the trade-off is significantly reduced usability of the terminal for routine work. Running affected builds only for trusted local sessions, or switching to an unmodified terminal until the upgrade can be deployed, bounds exposure but does not remediate the underlying flaw, and no reliable configuration-level block of the colour-control protocol is described in the provided data. Confirm applied version by checking 'kitty --version' against the v0.49.0 release (https://github.com/kovidgoyal/kitty/releases/tag/v0.49.0) and review the CNA advisory (https://secur0.com/en/cna/cve-list/cve-2026-95832-kitty-color-control-command-execution) for any updated guidance.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The flaw sits in kitty's colour-control escape-code handler, which implements the OSC 21 query protocol in kitty/window.py. When a client sends a colour query containing a field name kitty does not recognise, color_control() previously placed that field name into the reply and write_escape_code_to_child() in kitty/screen.c then wrote the reply to the pseudoterminal master - the same channel the shell reads as user keystrokes - without neutralising it for that shell. This is CWE-74 (improper neutralization of special elements in output used by a downstream component), i.e. an output-to-downstream-command injection rather than a memory-safety bug. The payload is filtered to printable ASCII before echoing (the ';' and '=' record/field separators are consumed as delimiters, but every other printable character survives), which is the restriction introduced in 0.47.3 as the fix for CVE-2026-54057 and is nonetheless enough to encode a shell command. The reply is framed as an OSC sequence carrying the escape code number, the field name, and the literal value '?', so the injected text arrives as terminal-emitted bytes. A terminating newline is supplied by handle_remote_ssh() in kitty/window.py, which writes the bytes yielded by get_ssh_data() in kittens/ssh/utils.py to the pseudoterminal master before any credential carried in the request is checked; those bytes begin with a newline. The 0.49.0 fix replaces the dict-based response with an ordered list of (field, value) tuples and reports unknown fields as 'unknown=<base64-encoded field name>' with padding stripped, so the escape code can no longer be used to emit arbitrary text.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Local because a program/output must write to the terminal (AV:L); needs the user to display malicious content (UI:R) but no privileges (PR:N); scope changes as the terminal injects into the shell (S:C) yielding full command execution (C/I/A:H).
Primary rating from Vendor (4daa8cea-433a-44bd-9456-53b127fc289a).
CVSS VectorVendor: 4daa8cea-433a-44bd-9456-53b127fc289a
Lifecycle Timeline
2DescriptionCVE.org
Improper Neutralization of Special Elements in Output Used by a Downstream Component in the colour control escape code handler in kitty from 0.47.3 before 0.49.0 allows a program writing to the terminal to execute an arbitrary command in the user's shell, because color_control() in kitty/window.py answers a query for an unrecognised field name by placing that field name into the reply, and write_escape_code_to_child() in kitty/screen.c then writes the reply to the pseudoterminal master, where it is not distinguishable from input typed by the user, without neutralising it for the shell that reads it. The payload is reduced to printable ASCII before the field name is echoed, which is the restriction introduced in 0.47.3 as the fix for CVE-2026-54057, and the record and field separators ; and = are consumed as delimiters, but every other printable character survives, which is sufficient to compose a shell command. A newline is available from handle_remote_ssh() in kitty/window.py, which writes the bytes yielded by get_ssh_data() in kittens/ssh/utils.py, the first of which begin with a newline, to the pseudoterminal master before any credential carried in the request is checked. The reply is framed as an OSC sequence carrying the escape code number, the field name, and the literal value ?. This results in execution of an attacker-chosen command with the privileges of the user running the terminal.
Executive ViewAI
Kitty terminal emulator versions 0.47.3 through 0.48.x are affected by a critical command injection vulnerability (CVE-2026-95832) that enables any on-screen output-such as a file, log, SSH banner, or web response-to execute arbitrary commands with the user's privileges. This unauthenticated local flaw (AV:L, PR:N, UI:P) poses a severe risk to developers, system administrators, and others who display untrusted content in kitty, potentially leading to data compromise or lateral movement. No public exploit identified at time of analysis, but with no vendor patch available, leadership should prioritize immediate mitigations.
No vendor patch available. Interim mitigations: avoid displaying attacker-controlled content in kitty (e.g., cat files from untrusted sources, SSH banners, web responses); consider disabling OSC 21 colour-control if configurable; or switch to an alternative terminal emulator until a fix is released.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.
EUVD-2026-87065
GHSA-hvwf-v5fx-xvj6
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB