Skip to main content
Every limit here is a gap between what the lane promises and what it does, or a boundary drawn on purpose. Read it alongside OpenSSH Differences, which is the other half: what sshd does that this lane does not.

The list


A value that crosses a read boundary

The session stream is read in 32 KB blocks, and each block is masked on its own. A value that begins in one block and ends in the next matches in neither, so it reaches the client in the clear — and because nothing matched, no masking event is recorded for it either. Two ways it happens:
  • Output longer than 32 KB. Every boundary is a place a value can be cut. cat a large file and the odds rise with its size.
  • A program that writes a value in more than one call. printf "user: alice@" followed by printf "example.com" is two writes, and can arrive as two reads.
Downloads are not affected. A file that a mask rule covers is read whole before it is rewritten, so there is no boundary inside it to cut a value on. The same is true of an upload, which is buffered before it is judged.

What to do about it

Treat masking on terminal output as a reduction, not a guarantee. Where a value must never be shown, deny the path instead of rewriting it — a denial is exact, a rewrite is per-block:
A fix has to hold bytes back until the next read confirms them, and the same length rule that makes strategy: mask the only strategy here forbids returning fewer bytes than were given. It is open work, and it needs a decision about what a user sees while bytes are held: a shell prompt has no trailing newline, so it would sit in the held tail and never be displayed.

Next

OpenSSH Differences

The assumptions carried over from sshd that do not hold here.

Configuration

Every attribute, the full capability surface, and what each one can carry.