OpenSSH is one of the most widely used tools in the world for secure shell (SSH) connections. It underpins countless secure environments, from small teams to large data centers. But even mature software isn’t immune from mistakes—especially subtle ones. On March 15, 2023, a security advisory revealed a flaw in OpenSSH’s ssh-add utility, tracked as CVE-2023-28531. This post explains the bug in plain language, shows you relevant code snippets, demonstrates how it can be exploited, and points you to official references.

TL;DR

CVE-2023-28531 is a vulnerability in ssh-add found in OpenSSH versions before 9.3. When you use smartcard-based SSH keys with ssh-add, destination constraints (which restrict which remote hosts the key can be used for) are not correctly applied. As a result, your private key may be used in ways you didn’t intend, potentially giving unauthorized access across multiple network hops.

What is ssh-add and Smartcard Authentication?

- ssh-add is a helper tool. It loads SSH private keys (including those from smartcards or hardware tokens) into ssh-agent, a program that keeps your keys safe in memory.
- Per-hop destination constraints allow you to restrict a loaded key to only work for specific destination hosts. This is useful for hopping through bastion hosts or keeping keys locked down.

Example usage:  

ssh-add -h host1.example.com /usr/lib/libykcs11.so


Here, the key is meant to work only for host1.example.com.

What Went Wrong?

For keys stored on a smartcard, ssh-add prior to OpenSSH 9.3 ignored destination constraints. This means that if you loaded a smartcard key meant only for host1.example.com, the agent would let you use that key for *any* SSH destination! This breaks the security model.

Relevant Commit

You can see the fix here.

Vulnerable Code – Before the Fix

The bug is subtle. In ssh-add.c, the per-hop constraint code was missing when adding keys via PKCS#11 (smartcard interface):

// Inside do_pkcs11() in ssh-add.c
if ((pin = read_passphrase("Enter passphrase for PKCS#11: ",
    RP_ALLOW_EOF)) == NULL)
    return -1;


The problem: the -h (host) restriction did not propagate to smartcard key loads.

`bash

ssh-add -h host1.example.com /usr/lib/libykcs11.so

The key can be abused on any server reachable via your ssh-agent, not just the intended one.

- If you’re using agent forwarding (ssh -A), all downstream hosts can ask your agent to authenticate to *any* host using that key, broadening the attack surface.

`bash

ssh-add -h allowedhost.example.com /usr/lib/libykcs11.so

Real-World Impact

If your organization relies on smartcards for stepping stones (like bastions) and assumes -h keeps keys bound to those systems, this bug means anyone with access to your agent can use the key anywhere. In environments with agent forwarding, this could lead to privilege escalation and lateral movement.

Update OpenSSH to 9.3 or newer. This fixes the bug.

- Manual workaround: Don’t use destination constraints with smartcard keys until you update. Assume keys might be usable everywhere.

References

- OpenSSH 9.3 Release Notes
- NIST NVD CVE-2023-28531
- OpenSSH Patch Commit (GitHub)

Conclusion

*CVE-2023-28531* is a reminder that security constraints can be subtle, especially with complex tools like ssh-agent and smartcards. If you handle sensitive infrastructure and rely on SSH key restrictions, check your OpenSSH version—update as soon as possible. Stay safe!

Timeline

Published on: 03/17/2023 04:15:00 UTC
Last modified on: 04/05/2023 17:44:00 UTC