iTerm2 RCE via cat readme.txt (CVE-2026-41253)

Want to learn ethical hacking? I built a complete course. Have a look!
Learn penetration testing, web exploitation, network security, and the hacker mindset:
→ Master ethical hacking hands-on
Hacking is not a hobby but a way of life!
iTerm2, the terminal emulator that ends up on almost every Mac developer’s machine, is vulnerable to a remote code execution attack that occurs when attacker-controlled text is displayed in the terminal, most commonly through reading a file with cat, less, or head. CVE-2026-41253, disclosed on April 17, covers every stable release up through version 3.6.9, which is still the current build on the downloads page because the fix that landed in source on March 31 has not yet shipped in a new release. Researchers at Calif Global turned a plain file-display operation into a full shell as the logged-in user by abusing a legitimate SSH integration feature that iTerm2 trusts by default, without a single click, a single download, or a single signature for any security tool to catch. 😏
The full exploit chain requires two things at the same time. The crafted escape sequences must reach the terminal through something like cat, and a small attacker-supplied helper script must exist in the local working directory with execute permissions at that exact moment. That second requirement is what shapes how this attack actually gets delivered.
- → A zip, tar, or other archive that bundles the crafted text file together with the helper script, unpacked into a folder, and the text file then viewed with cat, less, or head from inside that same folder
- → Cloned git repositories that carry both files in the same directory, viewed from within the local working copy after cloning
- → Compromised packages on npm, PyPI, Composer, or Homebrew that ship both pieces inside the source tree, affecting anyone who runs cat on a file from inside that directory
- → CTF challenge downloads and malware sample archives where the two files sit together and one of them gets opened during routine triage
- → Staged supply chain payloads in open source projects where both files have been in place long enough to pass review, waiting for the next iTerm2 user to run cat on the text file
iTerm2 has been the go-to terminal replacement on macOS for over a decade. It is the gold standard free option for developers, and inside the security community it is everywhere. Pentesters, reverse engineers, threat hunters, bug bounty researchers, red team operators. Anyone working in security from a Mac almost certainly has an iTerm2 window open somewhere on the desk right now.
iTerm2 has a feature called SSH Integration that gives it a richer understanding of remote sessions. When it2ssh is used to connect to a remote server, iTerm2 does not just pipe keystrokes through the SSH channel. It sends a small helper script to the remote side called the conductor, and that script becomes the protocol peer on the other end. The two sides then exchange messages about which shell is active, whether Python is installed, which directory is current, and what commands should run next.
The strange part is how those messages travel. There is no separate network connection for this protocol. The conductor talks back to iTerm2 by printing special escape sequences into the normal terminal output. Two specific codes do the heavy lifting: DCS 2000p is the code that tells iTerm2 to start listening as if a conductor session has begun, and OSC 135 is the code that carries the actual messages, things like begin a command, here is command output, end of command, and unhook.
This all works fine when the conductor on the remote side is real. But iTerm2 never actually checks whether the output claiming to be a conductor is coming from a trusted SSH session. It just sees the escape codes in its input stream, believes them, and starts acting on them. That is the whole bug in one sentence, and any terminal output that prints the right escape sequences can pretend to be the remote conductor while iTerm2 plays along.
Now put that together with a file.
A malicious readme.txt can contain a fake DCS 2000p line that tells iTerm2 the conductor has arrived, followed by fake OSC 135 replies. When the victim runs cat readme.txt, iTerm2 renders the contents and trips over the escape sequences. At that point iTerm2 starts its normal conductor workflow automatically, which means that when it asks for the shell the fake replies answer, and when it asks for the Python version the fake replies answer again, and there is no reason inside iTerm2’s state machine for the handshake to stop. After that handshake, iTerm2 believes it is time to send a real command to the remote conductor, so it builds a run request and base64-encodes it to ship across the line.
Except there is no remote, no SSH session on the other side, and no actual conductor reading those commands. The attacker controlled one of the parameters earlier in the fake handshake called sshargs, and chose the value carefully so that when iTerm2 base64-encodes the final run request, the last chunk of output comes out as ace/c+aliFIo. That string is not random. It is a crafted filename that works out as both a valid tail of the base64 encoding and a valid relative path on disk.
The base64 chunks get written into the pseudoterminal that iTerm2 is using. Because there is no actual SSH process reading them, the local shell sees them as plain input and tries to run them as commands. Most of those chunks fail as nonsense, but the last one does not. If the working directory contains a file called ace/c+aliFIo with execute permissions, the shell runs that file.
The CVSS score sits at 6.9 medium, and that rating seriously undersells what this actually means for the people who use iTerm2 the most. The score is held in the medium band by its AC:HIGH attack complexity rating, which captures that the exploit needs the crafted file, the helper script, and cat run from inside the same directory all at once. Without that complexity penalty, a bug with the same impact profile would score considerably higher. The 6.9 reflects the conditions that have to line up, not the consequences once the chain fires.
The full proof of concept is public on GitHub. That makes the exact technique available to defenders and researchers for study, and just as available to anyone else who decides to pick it up and run with it.
There is a second layer to this disclosure that has not gotten attention. On April 16, one day before this CVE went public, NIST announced it is ending routine enrichment of the National Vulnerability Database. Going forward only CVEs in CISA’s Known Exploited Vulnerabilities catalog, software used by the US federal government, or software classified as critical under Executive Order 14028 will receive full enrichment with severity scoring, affected-product lists, and CPE mapping. CVE-2026-41253 falls outside all three categories. The vulnerability scanners, asset inventories, and compliance dashboards that build their risk logic on NVD-enriched metadata may never see this bug weighted the way it deserves. The same week that AI is pushing the discovery rate higher, the public database most security tools trust is quietly narrowing its scope.
iTerm2 has been bitten by escape sequence vulnerabilities on a regular schedule for years. CVE-2019-9535 back in 2019, a tmux integration RCE. CVE-2023-46300 and CVE-2023-46301 in late 2023, escape sequence mishandling during tmux integration and file upload. CVE-2024-38395 and CVE-2024-38396 in the summer of 2024, title reporting combined with tmux integration for remote code execution. CVE-2025-22275 earlier this year, an information leak through framer logging. And now CVE-2026-41253.
Seven escape sequence bugs in seven years in the same terminal emulator. This is not a sequence of independent accidents. Terminal escape sequences were designed in an era when nobody modeled a threat actor sitting on the other side of the cable. The only way a terminal emulator knows that something is an instruction instead of text to display is that it starts with a special byte, so any attacker able to put those bytes into the input stream gets to steer the emulator. iTerm2 builds extra features on top of that foundation, and every extra feature creates another place where the trust line gets drawn in the wrong spot.
iTerm2 is mostly maintained by one person, George Nachman, who has been running the project for over a decade and funds it through community donations on Patreon. He got the report on March 30 and had the fix committed on March 31, the kind of one-day turnaround that is rare in open source of this size and one of the reasons the pattern has not grown worse than it already is. Respect to him for that.
The bug comes out of a month-long project called MAD Bugs, short for Month of AI-Discovered Bugs, run by Calif Global from late March through the end of April 2026, in partnership with OpenAI for this specific iTerm2 work. In that campaign, the team pairs human security researchers with large language models to audit well-known open source software at scale. The results this month alone include a Vim tabpanel RCE, multiple Emacs remote code execution vectors on file open, a full FreeBSD remote kernel RCE with a root shell written end to end by Claude, a radare2 zero-day, a Ghidra Server authentication bypass, an rsync audit seeded by Phrack articles, an nginx CVE, a Samsung TV firmware hack, an iPhone jailbreak writeup, a qmail audit turning up RCE, and this iTerm2 bug.
Eleven serious findings in a single month from one small team. The economics of vulnerability research are shifting hard, and iTerm2 is one data point in that shift.
Here is what actually reduces exposure right now.
→ Check the installed iTerm2 version first. The About iTerm2 menu shows it, or the command
defaults read com.googlecode.iterm2 CFBundleShortVersionStringin a terminal prints it. Anything up to and including 3.6.9 is vulnerable.→ Keep an eye on iterm2.com/downloads for a new stable release past 3.6.9. The fix is in the source tree but not yet in a shipped build at the time of writing this.
→ Homebrew does not give a free pass here. The stable cask for iterm2 is still 3.6.9, and the nightly cask currently points to a build from March 30, one day before the fix landed. Check the version the app itself reports, not what the package manager claims is installed.
→ For handling untrusted files, a different terminal emulator is the safer choice right now. Terminal.app, Alacritty, Kitty, Ghostty, and Wezterm do not implement the iTerm2 conductor protocol and are not vulnerable to this specific bug.
→ Never run cat, less, head, or tail on untrusted files directly on a production host. A disposable virtual machine with no shared clipboard and no shared folders is the right place for that kind of work. A hex viewer like xxd, or the command
od -c file, is a safer way to see the bytes of an unknown file from a real terminal.→ Disable SSH Integration in iTerm2 preferences if there is no active use for it. It is the feature the attack rides on, and most users do not know they have it turned on in the first place.
→ For malware analysts, treat every sample handling session as hostile input from the first second. A file that looks like a readme can carry a working exploit in plain text, and that changes the threat model around first-pass triage in a way that most existing workflows have not caught up with yet.
Hunting for trust failures like this one, chaining small footholds into full system compromise, and building the hacker mindset that spots these bugs in the first place is exactly what I cover in my ethical hacking course, including reconnaissance and OSINT, exploitation with Metasploit, web application attacks, WiFi cracking, network attacks, social engineering, privilege escalation, and the full attack chain from initial access to persistence.
Hacking is not a hobby but a way of life.
Sources:
→ Stay updated!
Get the latest posts in your inbox every week. Ethical hacking, security news, tutorials, and everything that catches my attention. If that sounds useful, drop your email below.