How Client-Side Denial of Service Happens in Node.js FTP Clients and How to Fix It
Vulnerability at a Glance
| Field | Detail |
|---|---|
| CVE | CVE-2026-44240 |
| Severity | HIGH |
| Package | basic-ftp < 5.3.1 |
| CWE | CWE-400: Uncontrolled Resource Consumption |
| Fix | Upgrade to basic-ftp 5.3.1 + add package.json override |
Direct Answer: CVE-2026-44240 is a client-side Denial of Service vulnerability in the
basic-ftpNode.js FTP client library (CWE-400). Versions before 5.3.1 fail to handle unterminated multiline FTP server responses, allowing a malicious server to hang the client indefinitely. Fix it by upgrading to 5.3.1 and pinning the version with apackage.jsonoverride.
Introduction
The openclaw-project-dashboard project uses basic-ftp to interact with FTP servers as part of its file management workflow. Trivy's software composition analysis flagged a HIGH-severity vulnerability in package-lock.json: the project was running basic-ftp version 5.3.0, which is vulnerable to a client-side Denial of Service attack via unterminated multiline FTP server responses (CVE-2026-44240).
This vulnerability is particularly interesting because the attack surface is on the client side — meaning your Node.js application is the victim, not the FTP server. If your application connects to any FTP server you don't fully control, or if an attacker can perform a man-in-the-middle attack on your FTP connection, they can exploit this flaw to hang your application process indefinitely.
The Vulnerability Explained
What Are Multiline FTP Responses?
The FTP protocol (RFC 959) allows servers to send multiline responses. A standard single-line FTP response looks like this:
220 Welcome to FTP server
A multiline response uses a specific format: the first line uses a hyphen (-) after the status code, and the final line uses a space after the same status code to signal termination:
220-Welcome to the FTP server
220-Please read the terms of service
220 Ready.
The critical detail: the client must keep reading lines until it sees the terminating line (status code + space). If the terminating line never arrives, the client is supposed to detect this and handle it gracefully.
The Flaw in basic-ftp 5.3.0
In basic-ftp versions prior to 5.3.1, the response parser does not properly enforce a termination condition when it encounters a multiline response that never sends its closing line. Instead of timing out or raising an error, the client continues waiting — consuming the event loop and blocking any further FTP operations.
The vulnerable behavior can be triggered with a crafted server response like:
220-This is a multiline response that never ends
220-Keep reading...
220-Still going...
[connection hangs here — no terminating "220 " line ever arrives]
Because basic-ftp 5.3.0 does not guard against this, the client process stalls. In a Node.js application, this means the event loop is blocked waiting for data that will never come, effectively causing a Denial of Service for any code path that depends on FTP operations completing.
Real-World Attack Scenario for openclaw-project-dashboard
Consider this concrete scenario for the openclaw-project-dashboard application:
- The dashboard connects to an FTP server to retrieve project files or upload build artifacts.
- An attacker who controls the FTP server (or who can perform a DNS hijack or MITM attack on the FTP connection) sends a malformed greeting or response that begins a multiline sequence but never terminates it.
- The
basic-ftp5.3.0 client in the dashboard hangs, waiting for the response to complete. - The dashboard's file operations stall. Depending on how the application handles this, the entire Node.js process may become unresponsive, taking down the dashboard for all users.
This is especially dangerous in CI/CD pipelines or automated deployment workflows where FTP connections are made programmatically without human oversight — a hang in these contexts can silently block deployments.
Why This Is Classified HIGH Severity
- No authentication required on the attacker's part — the malicious response is sent before any credentials are exchanged (e.g., in the FTP server greeting).
- Full process hang — not just a slow operation, but an indefinite block.
- Broad applicability — any code path in
openclaw-project-dashboardthat initiates an FTP connection is affected.
The Fix
The fix required changes to two files: package-lock.json and package.json.
1. Upgrading basic-ftp in package-lock.json
The core change was upgrading basic-ftp from 5.3.0 to 5.3.1:
Before (vulnerable):
"node_modules/basic-ftp": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz",
"integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w=="
}
After (patched):
"node_modules/basic-ftp": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz",
"integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw=="
}
The new integrity hash (sha512-bopVNp6ugyA150DDu...) cryptographically verifies that the installed package is exactly the patched 5.3.1 release — not a tampered or older version.
2. Adding a package.json Override
This is the critical second step that many developers miss. Simply updating package-lock.json is not sufficient if basic-ftp is also pulled in as a transitive dependency by another package in the tree. To guarantee that no nested dependency can re-introduce basic-ftp 5.3.0, an overrides entry was added to package.json:
Before:
{
"devDependencies": {
"@playwright/test": "^1.59.1"
}
}
After:
{
"devDependencies": {
"@playwright/test": "^1.59.1"
},
"overrides": {
"basic-ftp": "5.3.1"
}
}
The overrides field (supported in npm 8.3+) forces npm to resolve basic-ftp to exactly 5.3.1 throughout the entire dependency tree — direct and transitive. This is a defense-in-depth measure that prevents the vulnerability from sneaking back in via a nested dependency update.
What Changed Inside basic-ftp 5.3.1?
The 5.3.1 patch adds proper termination detection to the multiline FTP response parser. The fix ensures that if a server response begins a multiline sequence (line ending with - after the status code) but never delivers the closing line, the parser will either time out or raise a parse error — rather than waiting indefinitely. Valid, well-formed FTP responses are completely unaffected.
Prevention & Best Practices
1. Use Software Composition Analysis (SCA) in CI/CD
Tools like Trivy, Snyk, and Dependabot scan your package-lock.json for known-vulnerable dependency versions. This vulnerability was caught by Trivy's rule CVE-2026-44240. Integrate SCA scanning into every pull request pipeline.
2. Always Add npm Overrides for Security Patches
When a transitive dependency has a known CVE, don't rely solely on updating package-lock.json. Always add an overrides entry in package.json:
"overrides": {
"vulnerable-package": "safe-version"
}
For Yarn users, use resolutions. For pnpm, use pnpm.overrides.
3. Implement FTP Connection Timeouts at the Application Layer
Even with the patched library, it's good practice to set explicit timeouts on FTP operations in your application code:
const client = new ftp.Client();
client.ftp.timeout = 30000; // 30 second timeout
This provides an additional layer of protection against any future response-parsing issues.
4. Prefer SFTP or FTPS Over Plain FTP
Plain FTP transmits data (including credentials) in cleartext and is more susceptible to MITM attacks that could exploit vulnerabilities like this one. Where possible, use SFTP (SSH File Transfer Protocol) or FTPS (FTP over TLS).
5. Keep Dependencies Minimal and Audited
Run npm audit regularly and automate dependency updates with tools like Renovate or Dependabot. The smaller and more up-to-date your dependency tree, the smaller your attack surface.
Relevant Standards
- CWE-400: Uncontrolled Resource Consumption
- OWASP A06:2021: Vulnerable and Outdated Components
Key Takeaways
- Unterminated multiline FTP responses are a real attack vector:
basic-ftp5.3.0's response parser has no termination guard, meaning a malicious server can hang your Node.js process with a single malformed response line. - Updating
package-lock.jsonalone is not enough: Theoverridesentry inpackage.jsonis essential to prevent transitive dependencies from re-introducing the vulnerable5.3.0version. - The attack requires no credentials: The malicious response can be delivered in the FTP server greeting, before any authentication occurs — making the attack trivially easy to execute.
- SCA tools catch what code review misses: This vulnerability was not visible in application source code; it lived in
package-lock.jsonand was only caught by Trivy's dependency scanning. - FTP clients in Node.js deserve the same security scrutiny as HTTP clients: DoS vulnerabilities in protocol parsers are just as dangerous as injection vulnerabilities in business logic.
How Orbis AppSec Detected This
- Source: The tainted data enters via the FTP server's response stream — specifically, a multiline response that begins with a
220-(or similar status-hyphen) prefix but never delivers the terminating220(status-space) closing line. - Sink: The dangerous call site is
basic-ftp's internal response parser, which reads lines from the FTP socket in a loop without a maximum-iteration or timeout guard in version 5.3.0. - Missing control: No termination bound or read timeout was enforced on the multiline response accumulation loop, allowing an infinite wait on attacker-controlled input.
- CWE: CWE-400 — Uncontrolled Resource Consumption
- Fix:
basic-ftpwas upgraded from5.3.0to5.3.1inpackage-lock.json, and anoverridesentry was added topackage.jsonto pin the safe version across the entire dependency tree.
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-44240 is a reminder that Denial of Service vulnerabilities don't always come from your own code — they can hide in the protocol parsers of the libraries you depend on. In openclaw-project-dashboard, basic-ftp 5.3.0's failure to handle unterminated multiline FTP responses meant that any FTP connection to an untrusted or compromised server could hang the entire application.
The fix is straightforward but has two required parts: upgrading the package in package-lock.json and adding an overrides entry in package.json. Miss the second step, and the vulnerability can silently return through a transitive dependency update. With both changes in place, the application is protected against this specific attack vector, and the fix is future-proofed against dependency tree reshuffling.
Treat your package-lock.json as a security artifact, not just a reproducibility tool. Run SCA scans on every commit, and let automated tools like Orbis AppSec catch what manual code review cannot.