mscdex / mscdex/ssh2

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

Open Beginner friendly
#1,505 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
5.8k
Forks
734
PR merge metrics
No merged PRs in 30d

Description

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.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in lib/client.js at the CHANNEL_DATA handler around lines 580-585, then inspect the CHANNEL_EXTENDED_DATA handler for the same receive-window logic. Verify the window check against payload length, cover oversized payloads and subsequent packets, and run the existing test suite to confirm that data beyond the advertised window is no longer buffered.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.