The terrapin attack is a prefix truncation attack on the SSH secure channel. An attacker sitting on the network does not break SSH encryption. Instead, they trim a few messages off the start of the encrypted conversation so carefully that neither end notices anything is missing. Because SSH numbers its messages but the two ends never compare those numbers after the handshake, deleting a message early and inserting a matching one earlier keeps the counts lined up, and the channel starts in a state the attacker shaped. This post explains how SSH sequences its packets, why truncation goes undetected, what the attacker gains, and why the strict handshake countermeasure closes it. It was disclosed in 2023 and tracked as CVE-2023-48795.
What the terrapin attack changes
SSH protects a session in two stages. First the two ends run a key exchange, agreeing on keys and on the algorithms they will use. Then every packet after that is wrapped in the binary packet protocol, encrypted and authenticated so it cannot be read or altered in flight. The integrity check uses a running sequence number: each packet carries an implicit counter, and the authentication covers that counter, so a packet cannot be reordered, replayed, or dropped without the check failing.
That is the promise. The terrapin attack shows the promise has a gap at the seam between the handshake and the encrypted channel. The sequence number counter starts ticking during the handshake, while some messages are still sent in the clear. An attacker who adds a harmless message in the clear early, then removes a real encrypted message later, can keep the final counter exactly where the honest run would have left it. The integrity check sees consistent numbering and raises no alarm, even though the transcript was edited.
How prefix truncation stays invisible
The trick is an accounting one. During the handshake, SSH allows certain optional or ignorable messages. The attacker injects one of these in the clear before encryption starts, which bumps the sequence counter by one on that side. Then, once the channel is encrypted, the attacker deletes the first real encrypted message. That deletion would normally shift every later sequence number by one and break the very next integrity check. But the earlier injected message already shifted the count the other way, so the two cancel. The counter the two ends expect still matches. The deleted message is simply gone, and nothing downstream reveals that it ever existed.
honest run: ... [msgA] [msgB=N] [msgC=N+1] ...
attacker run: [injected=clear] ... [msgB deleted] [msgC=N] ...
# counter at msgC lines up, integrity check passes
So the attacker cannot read the encrypted traffic, but they can chop a known message off the front of the secure channel. That is the prefix truncation. The first thing the secure channel was supposed to say is silently removed, and the session continues as if it was never sent.
Nothing was decrypted and no key leaked. The attacker only deleted the opening of the conversation, and the integrity check, counting by a number that still added up, waved it through.
Why a deleted opening message matters
Removing the first message of a secure channel sounds minor until you see what that message often is. SSH sends an extension negotiation message, SSH_MSG_EXT_INFO, right at the start of the encrypted channel. It tells the other end which extra features and, in some cases, which signature algorithms are in play. If an attacker deletes that message, they strip the negotiated extensions without either end knowing.
In practice this lets an attacker turn off a security feature that was agreed during the handshake, for example a countermeasure that protects against a weakness in certain signature methods. The endpoints believe the feature is active because they negotiated it. It is not active, because the message announcing it never arrived. This is a downgrade achieved by deletion rather than by rewriting the negotiation, which makes it a close relative of the cipher downgrade attack, where a man in the middle steers two ends onto weaker crypto. There the attacker edits the offered options. Here the attacker deletes the message that would have switched a protection on.
Which connections were affected
The attack does not work on every SSH connection. It depends on specific modes where the sequence number handling at the handshake boundary lines up with what the attacker needs, most notably the ChaCha20-Poly1305 mode and certain encrypt then MAC CBC modes. Connections using other authenticated modes were not exposed in the same way. That is why the practical advice was not panic but patch, since the fix is clean and the exposure is bounded to particular algorithm choices.
The fix: the strict handshake countermeasure
The root cause is that the sequence number counter spanned both the unauthenticated handshake and the authenticated channel, so a message injected in the clear could offset a deletion made later. The countermeasure, called strict key exchange or the strict handshake, fixes exactly that.
- Reset the sequence number after key exchange. With the strict handshake, the packet counter is set back to zero once keys are established. A message the attacker injected in the clear before that point no longer offsets anything afterward, because the count restarts. A deletion in the encrypted channel now shifts the numbering and the next integrity check fails, which is what should have happened all along.
- Refuse unexpected messages during the handshake. The strict handshake also rejects the optional messages an attacker would inject during key exchange, so the offset move is not even available.
- Patch both ends. The countermeasure only applies when both the client and the server support it, so updating only one side is not enough. Update both, and confirm the strict handshake is actually in use.
The broader lesson is familiar. An integrity check is only as strong as the exact thing it covers, and a counter that is trusted across a trust boundary can be gamed on one side of it. For more attacks in this family, start at our hub on cryptographic oracle attacks, and for more write ups from the ground up see the vulnerability basics category.
The assumption that breaks
The assumption the terrapin attack breaks is that an authenticated channel authenticates its own beginning. The messages inside were protected, but the boundary where the counter started was not, and an attacker worked the seam. The secure channel looked intact to both ends while its first words had been cut away.
Asking whether a handshake step is actually authenticated from its very first byte, rather than assuming the channel protects everything once encryption turns on, is exactly the kind of question an autonomous researcher that tests assumptions is built to ask. Learn more about that approach on our about page.
Frequently asked questions
What is the terrapin attack?
It is a prefix truncation attack on SSH, disclosed in 2023 as CVE-2023-48795. An attacker on the network deletes the first messages of the encrypted SSH channel without being detected, by injecting an ignorable message in the clear during the handshake so the sequence number counter still lines up after the deletion. The attacker cannot read the traffic but can cut the opening of the secure conversation.
Why does the integrity check not catch the truncation?
SSH numbers its packets and the authentication covers that running count, so a dropped packet normally breaks the next check. The problem is that the counter starts during the handshake while some messages are still in the clear. An attacker injects one clear message early and deletes one encrypted message later, and the two offsets cancel, so the counter both ends expect still matches and no alarm fires.
What can an attacker gain from the terrapin attack?
Deleting the first message of the secure channel can strip the extension negotiation message that SSH sends right after key exchange. That lets an attacker silently turn off a security feature both ends thought they had agreed on, such as a countermeasure protecting certain signature methods. It is a downgrade achieved by deleting a message rather than by rewriting the negotiation.
How do you fix the terrapin attack?
Apply the strict key exchange countermeasure, often called the strict handshake, which resets the packet sequence number to zero after key exchange and refuses unexpected messages during the handshake. With the counter reset, an injected clear message no longer offsets a later deletion, so truncation breaks the next integrity check. Both the client and the server must support it, so patch both ends.
Put an autonomous researcher on your own systems
UnboundCompute is an autonomous security researcher that reasons about how an application fits together and proves the access control and injection bugs it finds. We are opening a small number of founding design partner seats: private early access pointed at a staging target you choose, and a say in what it looks for. If your team ships software worth pressure testing, apply to the design partner program.
