Skip to content

[Security] Receive window check rejects only exactly-zero credit — negative window enables unbounded buffering (CWE-400) #1505

Description

@afldl

Summary

The ssh2 package for Node.js (tested: 1.17.0, ref 318d447ce3ac) does not correctly enforce its advertised SSH channel receive window. The inbound CHANNEL_DATA handler rejects data only when the remaining window is exactly zero, then subtracts the payload length regardless — a single oversized payload drives the window negative, after which every subsequent packet passes the guard and is buffered. Post-authentication memory-exhaustion DoS.

Affected version

ssh2 (npm), default branch, ref 318d447ce3ac (latest as of 2026-07).

Root cause

lib/client.js (CHANNEL_DATA handler):

if (channel.incoming.window === 0)   // line 580: only EXACTLY zero
  return;
channel.incoming.window -= data.length;   // line 583: can go negative
if (channel.push(data) === false) {       // line 585: buffered anyway

Client advertises MAX_WINDOW = 2 * 1024 * 1024 (2 MiB). The guard should be data.length > channel.incoming.window; once window goes negative, === 0 never matches again → unbounded buffering.

PoC (end-to-end)

[server] channel open; client advertised window = 2097152 bytes
[driver] child baseline VmRSS=60600 kB
[server] sent 18874368 bytes of CHANNEL_DATA (16777216 beyond advertised window)
[driver] child VmRSS peak=88784 kB (growth=28184 kB = 27.5 MiB)
[driver] VERDICT: CONFIRMED

Client advertised 2 MiB window; RSS grew 27.5 MiB while 16 MiB was pushed beyond window.

Suggested fix

if (data.length > channel.incoming.window)
  return;  // or disconnect
channel.incoming.window -= data.length;

Apply to both CHANNEL_DATA and CHANNEL_EXTENDED_DATA handlers.

CWE

CWE-400 (Uncontrolled Resource Consumption), post-authentication.

Credit

Reported by zhangph (afldl), 2026-07.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions