Security Model¶
This page states what SSHClient protects against, what evidence backs that, and what it does not yet do. It reflects the 2026-08 security review, whose findings were either fixed (with regression tests) or are listed below as limitations.
Protections¶
Confidentiality & integrity of the session. After key exchange, all traffic is AES-128-CTR encrypted and HMAC-SHA-256 authenticated, with per-direction keys derived per RFC 4253 from a Diffie–Hellman group14 (2048-bit MODP) shared secret and SHA-256. Packets failing MAC verification abort the session.
Server authentication. The server's rsa-sha2-256 signature over the
exchange hash is verified with PKCS#1 v1.5, and the host key is checked
against known_hosts (policy details). A live
man-in-the-middle — a second, fully functional server presenting a
different key — is refused before authentication; this exact scenario is
an automated test (Test_HostKey_MITM).
Credentials. The password (or the public-key signature) is only ever sent inside the encrypted, server-authenticated transport, after the host key has passed both checks.
Malformed input. The packet length word from the wire is capped at 256 KB before any allocation (a corrupt or malicious peer gets a clean error, not a memory blow-up), and MAC comparison examines every byte with no data-dependent early exit.
Randomness. The key-exchange cookie and the 256-bit DH private
exponent are drawn under ⎕RL←⍬ 2 — Dyalog's operating-system RNG
(/dev/urandom / CryptGenRandom), which is cryptographically
appropriate. Packet padding uses the workspace RNG; padding is encrypted
and is not key material.
Verification evidence¶
The test suite (50 tests, run in CI on every push) validates:
- SHA-256 against NIST FIPS 180-2 vectors; HMAC-SHA-256 against RFC 4231; AES-128-CTR against NIST SP 800-38A, including counter continuity
- modular exponentiation against known values plus a DH commutativity proof over the real group14 prime
- RSA sign/verify cross-checked against OpenSSL in both directions, with bit-flipped / truncated / garbage / wrong-message signatures all refused
- the full stack against real OpenSSH: password and key auth, exec, SFTP
binary round-trips independently confirmed by remote
sha256sum, TOFU pinning, strict mode, and the live-impostor MITM refusal
See Testing & CI.
Current limitations¶
| Area | Status |
|---|---|
| Rekeying | not implemented; very long sessions do not renegotiate keys |
| Password in memory | Password is a plain public field for the object's lifetime and appears in Config output |
| Algorithm agility | small preference lists negotiated per RFC 4253 — see Algorithms & Limitations; a server offering none of a slot's list still fails (cleanly) |
Reporting¶
If you find a security problem, please include the Debug output
(bit 4 = packet trace) from a test server only — traces of real
sessions contain sensitive material.