Safeguard
Vulnerability Analysis•

golang.org/x/crypto v0.56.0: Two SSH Connection Deadlocks Fixed

A malicious SSH peer could deadlock a whole connection in Go's x/crypto/ssh. Both clients and servers are affected. Upgrade to v0.56.0 and rebuild.

Safeguard Security Team
5 min read

On 2 September 2026 the Go team released golang.org/x/crypto v0.56.0, fixing two denial of service bugs in the ssh package: CVE-2026-56855 and CVE-2026-78662. In both, a malicious peer could send crafted channel traffic that deadlocked the entire SSH connection. The fix had been pre-announced on golang-announce on 28 August.

These are not standard library bugs, so a new Go toolchain does not fix them. You need to bump the module and rebuild.

What's affected

Module golang.org/x/crypto, package golang.org/x/crypto/ssh, all versions before v0.56.0. The Go vulnerability database lists the same four entry points for both issues: Dial, NewClientConn, NewControlClientConn and NewServerConn. That means SSH clients and SSH servers written with this package are both in scope.

CVE-2026-56855 (GO-2026-6355): deadlock on an established channel. After a channel was established, a malicious peer could send crafted messages that deadlocked the connection. The fix handles every channel message defined in RFC 4254, processes global requests explicitly, and treats anything else as a protocol error that tears the connection down instead of buffering and blocking. Go issue 81317.

CVE-2026-78662 (GO-2026-6354): deadlock on a channel that isn't established yet. A channel sits in the connection's channel list before it is usable. A peer could flood that channel's incoming requests and deadlock the connection. The fix adds an "established" state. Until a channel is established, the package drops every packet except the open confirmation or failure, without blocking. Go issue 81316.

Both were reported by Will Mortensen.

The impact is availability. A deadlocked connection hangs whatever goroutine is waiting on it. For a server, that ties up the goroutines serving the attacker's connection. For a client, it is a hung job: a deploy step, a backup, a bastion hop or a Git operation that never finishes.

How to check if you're exposed

In each Go module:

# What version does the build actually use?
go list -m golang.org/x/crypto

# Is the ssh package in the build graph at all?
go list -deps ./... | grep '^golang.org/x/crypto/ssh$'

# Does your code reach the affected functions?
govulncheck ./...

govulncheck reports GO-2026-6355 and GO-2026-6354 only if your code calls into the affected symbols, which is the question that matters here.

For binaries you ship or run but didn't build, read the embedded module list:

go version -m ./path/to/binary | grep golang.org/x/crypto

Anything below v0.56.0 that links x/crypto/ssh needs a rebuild. Remember that x/crypto is often a transitive dependency. A tool that only talks to Git over SSH, or a Terraform-style provisioner, can pull it in without your code importing it directly.

What to do now

  1. Update the module:
    go get golang.org/x/crypto@v0.56.0
    go mod tidy
    
  2. Rebuild and redeploy every binary that links x/crypto/ssh. Go links statically, so the fix is not live until the binary is replaced.
  3. Prioritise multi-user SSH servers. In the SSH protocol, channels are opened after user authentication, so for a server the realistic attacker is anyone who can log in: customers of a Git host, partners on an SFTP gateway, users of a bastion. For a client, it is any server the client connects to.
  4. Add timeouts on the client side. Wrap SSH sessions in contexts with deadlines, and set a Timeout in ssh.ClientConfig for the dial. A deadlock that times out becomes a failed job, not a hung pipeline.
  5. Watch vendored copies. If you vendor dependencies, confirm vendor/modules.txt shows v0.56.0 after the bump.

Why it matters

The Go team publishes x/ module fixes on the same golang-announce list as toolchain releases, but they need a different response. A toolchain fix lands when you rebuild with the new Go version. An x/crypto fix lands only when every module that depends on it moves to the new version, and then every binary is rebuilt. That second step is easy to miss for internal tools and CI images that nobody rebuilds unless something breaks.

Denial of service bugs in protocol libraries also tend to be underrated. A hung SSH client in a deploy pipeline can block releases, including the release carrying the fix for something more serious.

Try it yourself

Pick three Go binaries your team runs in production or CI and run go version -m against each. Record the golang.org/x/crypto version, then check whether the binary was built after 2 September 2026. Any binary without an x/crypto line at all doesn't use the module, which is also worth knowing.

Click through it at your own pace, or open it full screen.

Quick check

You upgraded to the latest Go toolchain on 3 September. Are you protected?

Not necessarily. These fixes are in the golang.org/x/crypto module, not the standard library. You need x/crypto v0.56.0 in your module graph and a rebuild.

Your service only uses x/crypto/ssh as a client to push backups. Is it affected?

Yes. Dial and NewClientConn are listed as affected symbols. A malicious or compromised server could deadlock the connection and hang the backup job.

What does the fixed package do with unexpected messages on an established channel?

It treats them as a protocol error and tears down the connection, instead of buffering them and blocking.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.