-Infinity
0

Vendor Risk Score

See how kitty compares to other vendors in security performance

View Risk Score →
Severity
5.6
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:A/VC:H/VI:L/VA:N/SC:H/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Missing Authorization in the askpass escape code handler in kitty from 0.25.0 before 0.49.0 allows a local user other than the one running the terminal to obtain the text typed into a prompt that kitty itself displays, because handleremoteaskpass() in kitty/window.py opens the POSIX shared memory object named in the escape code, parses a prompt definition out of it, and writes the user's answer back into an object of that same name, without at any point checking that the object is owned by the user running kitty or that its permissions exclude other users. The equivalent consumer of the same SharedMemory class in the ssh kitten performs exactly that check; the askpass path did not. The handler is reached through a device control string processed from the byte stream of the window, so the attacker must also cause bytes of their choosing to be displayed by the victim's terminal. Where the POSIX shared memory namespace is shared between the two users, a second local user can create an object with permissions that allow the victim to read and write it, cause the victim's kitty to render a prompt of the attacker's choosing, including a masked password prompt, and read the typed secret back out of the object afterwards. The prompt text is additionally passed to the display without control character sanitisation, so it can overwrite the warning line kitty prints above it. The answer is written by reopening an object of that name when the user answers, rather than through the handle already held. This results in disclosure of a secret typed by the victim to a second local user, and does not require any privilege on the victim's account.

First published (updated )
Severity
4.6
Use After Free
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Use After Free in the drag source path of the drag and drop protocol in kitty from 0.47.0 before 0.49.0 allows a program writing to the terminal to cause the terminal to read from and write to freed heap memory, because dragremotefiledata() in kitty/dnd.c holds a DragRemoteItem pointer into an array it does not own, calls topleveldatafordrag() or subdirdatafordrag(), and then continues to use that pointer. Those helpers, and addpayload() and populatedirentries() which they call, report errors through the abrt() macro, which expands to canceldrag() followed by a plain return, and canceldrag() calls dragfreeoffer(), which frees the array the pointer refers to. The helpers return void, so the caller receives no indication that the teardown happened, and proceeds to call allchildrencomplete() on the freed pointer, which dereferences it, and then to write through it. That dereference is guarded by a local flag that is set when the request carries no payload and announces no further data, which is the same condition that selects the finalisation block of addpayload(), so the error paths in that block reach it: a create that fails because an entry of the same name already exists, because the client may declare two entries with one name and the create operations use OCREAT with OEXCL and symlinkat(), a mkdirat() failure other than EEXIST, and the directory entry allocation paths. Both branches reach it. In the top level branch the caller's pointer is never cleared, so clearing the owning structure's own pointers during teardown does not help. In the sub directory branch subdirdatafordrag() sets the caller's pointer to NULL on entry and assigns it only after its own last error path, so its own aborts leave the caller with NULL and are stopped by a null check, but it then calls addpayload() with that pointer set, and an abort there leaves the caller holding a freed child node inside the item tree, which dragfreeoffer() frees by recursion. This results in undefined behaviour in the terminal process, reachable from the byte stream of any program running in the window.

First published (updated )
Severity
6
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Missing Authorization in the drop handling path of the drag and drop protocol in kitty from 0.47.0 before 0.49.0 allows a program writing to the terminal to obtain the contents of files dragged over the window even when the user never completes the drop, because dropenqueuerequest() in kitty/dnd.c serves a drag data request without first checking the drop state of the window, so a client that issues the request while a drag is merely hovering receives the data offered for the drag. In the same file, dropleftchild(), which runs when the drag leaves the window without a drop having occurred, releases the offered MIME list but retains the pending request state, the open file descriptor and its main loop transfer timer, the directory handles, the URI list and the pending MIME name, so a client can continue to read through a retained directory handle, and an in-flight file transfer continues to stream, when no drag is in progress. The file contents are read from the filesystem by the kitty process itself using the paths the drag source offered. This results in disclosure of the contents of files the user moved over the window without ever releasing them into it.

First published (updated )
Severity
9.3
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

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 colorcontrol() in kitty/window.py answers a query for an unrecognised field name by placing that field name into the reply, and writeescapecodetochild() 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 handleremotessh() in kitty/window.py, which writes the bytes yielded by getsshdata() 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.

First published (updated )
Severity
4.6
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:N/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Improper Link Resolution Before File Access in the drag source staging path of the drag and drop protocol in kitty from 0.47.0 before 0.49.0 allows a program writing to the terminal to create files and directories at paths outside the staging directory, because subdirdatafordrag() in kitty/dnd.c resolves a descendant of the staged item tree by constructing a path string and opening it with safeopen(path, ODIRECTORY | ORDONLY, 0) rather than by walking the tree one component at a time, so a client that declares two entries with the same name, the first a symlink whose target is an arbitrary absolute path and the second a directory, causes mkdirat() to fail with EEXIST, which the code ignores, and causes the subsequent path resolution to follow the symlink and return a directory descriptor outside the staging directory, which is then passed as the dirfd argument to addpayload() and used for every further create operation on that item and its descendants. Entry names are sanitised against path separators and dot components, but symlink targets are not validated. Files are created with OCREAT | OWRONLY | OEXCL at mode 0644, so existing files cannot be overwritten, and directories are created with mkdirat() at mode 0755, so the attacker can create intermediate directories that did not previously exist. This results in the creation of files and directories at any path writable by the user running kitty, provided the symlink target is an existing directory.

First published (updated )
Severity
6.8
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Out-of-bounds Write in the natural width branch of the text sizing protocol in kitty from 0.40.0 before 0.49.0 allows a program writing to the terminal to write past the end of a fixed-size buffer, because screenhandlemulticellcommand() in kitty/screen.c appends each codepoint of a grapheme cluster with lc.chars[lc.count++] = ch without any capacity check, while lc is declared by the RAIIListOfChars macro as a four-element chartype array in the function's stack frame, so an OSC 66 escape code whose payload carries a grapheme cluster longer than four codepoints writes beyond that buffer, one 32-bit value per additional codepoint, in the order the codepoints appear. Where the cluster is preceded in the same payload by a sequence that causes an intermediate flush, the buffer is first migrated to the heap by ensurespaceforchars() and the write occurs past the heap allocation instead. This results in termination of the kitty process and therefore of all its windows, tabs and child processes.

First published (updated )
Severity
7.3
Command Injection, CRLF Injection
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Kitty is a cross-platform GPU based terminal. Prior to 0.48.2, the @kitty-echo and @kitty-ssh DCS handlers in kitty/window.py write unauthenticated data to the child shell's stdin, where handleremoteecho accepts printable shell command characters and handleremotessh calls getsshdata in kittens/ssh/utils.py, which emits a newline; chaining the handlers can execute attacker-controlled commands when a user displays untrusted terminal data. This issue is fixed in version 0.48.2.

First published (updated )
Severity
8.8
Buffer Overflow
AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H

Kitty is a cross-platform GPU based terminal. Versions 0.46.2 and below contain a heap buffer overflow in loadimagedata() that allows any process which can write to the terminal's stdin to crash kitty immediately. The vulnerability is triggered by a single APC graphics protocol command with a PNG format declaration (f=100) whose payload exceeds twice the initial buffer capacity. The overflow is attacker-controlled in both length and content, causing DoS and potentially escalation to RCE itself. This issue has been fixed in version 0.47.0.

1 / 2
Source: MITRE
First published (updated )
Severity
9.9
Integer Overflow
AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:H

Kitty is a cross-platform GPU based terminal. In versions 0.46.2 and below, the handlecomposecommand() function in kitty/graphics.c performs bounds validation on composition offsets using unsigned 32-bit arithmetic that is subject to integer wrapping, potentially leading to Heap Buffer Over-Read/Write. An attacker who can write escape sequences to a kitty terminal (e.g., via a malicious file, SSH login banner, or piped content) can supply crafted xoffset/yoffset values that pass the bounds check after wrapping but cause massive out-of-bounds heap memory access in composerectangles(). No user interaction is required. No non-default configuration is required. The attacker only needs the ability to produce output in a kitty terminal window. This issue has been fixed in version 0.47.0.

1 / 2
Source: MITRE
First published (updated )
Severity
5
Race Condition
AV:L/AC:H/PR:L/UI:R/S:U/C:N/I:H/A:L

Kitty is a cross-platform GPU based terminal. In versions prior to 0.47.2, a local privilege escalation vulnerability exists in kitty's file transmission protocol where a child process running in the terminal can write to arbitrary files on the filesystem by exploiting a TOCTOU (Time-of-Check-Time-of-Use) race condition between symlink validation and file creation. The os.open() call used to create files does not use ONOFOLLOW, allowing an attacker to create a symlink between the initial stat check and the actual file open, causing the write to follow the symlink to an arbitrary destination. Version 0.47.2 fixes the issue.

1 / 2
Source: MITRE
First published (updated )
Severity
7.3
Code Injection
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Kitty is a cross-platform GPU based terminal. In versions prior to 0.47.3, kitty's OSC 21 (color-control) query reply reflects attacker-controlled bytes, including newlines, into the shell's input without sanitization. Version 0.47.3 fixes the issue.

1 / 2
Source: MITRE
First published (updated )
Severity
7.6
AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:H/A:L

Kitty is a cross-platform GPU based terminal. In versions 0.47.0 and 0.47.1, kitten dnd can allow a malicious remote drag-and-drop source to overwrite or truncate arbitrary files writable by the local kitty user. Remote text/uri-list drops are staged in a temporary directory, but on case-sensitive filesystems duplicate remote basenames are not de-duplicated. An attacker can first create a staged symlink and then send a same-name regular-file entry. The regular-file write uses utils.CreateAt() / openat(ORDWR|OCREAT|OTRUNC) without ONOFOLLOW, so it follows the attacker-created symlink and writes outside the staging directory before final overwrite confirmation runs. This appears related in class to the file-transfer symlink advisory, but it is a different bug: it affects kitten dnd remote drag-and-drop staging, uses different vulnerable code (kittens/dnd/drop.go and tools/utils/fileatfd.go), and reproduces on commit 4aa4a5c0567a92553a8c20a88a4352da637fca5d, after the file-transfer ONOFOLLOW fix. Version 0.47.2 patches the issue.

First published (updated )
Severity
7.8
EPSS
0.01%
AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N

openactions.py in kitty before 0.41.0 does not ask for user confirmation before running a local executable file that may have been linked from an untrusted document (e.g., a document opened in KDE ghostwriter).

First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203