Back to Blog
high SEVERITY7 min read

How Client-Side Denial of Service Happens in Node.js FTP Clients and How to Fix It

CVE-2026-44240 is a client-side denial of service vulnerability in the basic-ftp Node.js library that allows attackers to crash FTP clients by sending malformed, unterminated multiline FTP responses. Upgrading from version 5.0.5 to 5.3.1 patches this critical flaw that could have disrupted any application using the vulnerable library for FTP operations.

O
By Orbis AppSec
Published July 22, 2026Reviewed July 22, 2026

Answer Summary

CVE-2026-44240 is a client-side denial of service vulnerability (CWE-400: Uncontrolled Resource Consumption) in basic-ftp for Node.js versions prior to 5.3.1. The vulnerability occurs when an FTP server sends malformed, unterminated multiline responses that the client fails to properly validate, causing infinite loops or memory exhaustion. The fix upgrades basic-ftp to version 5.3.1, which implements proper termination detection and response validation to prevent resource exhaustion attacks from untrusted FTP servers.

Vulnerability at a Glance

cweCWE-400 (Uncontrolled Resource Consumption)
fixUpgrade to basic-ftp 5.3.1 which implements robust multiline response parsing with proper termination detection
riskRemote attackers can crash FTP client applications by sending specially crafted FTP responses
languageNode.js (JavaScript)
root causebasic-ftp 5.0.5 failed to properly validate FTP multiline response terminators, allowing infinite loops or resource exhaustion
vulnerabilityClient-Side Denial of Service via Unterminated Multiline FTP Responses

How Client-Side Denial of Service Happens in Node.js FTP Clients and How to Fix It

Introduction

In a production Node.js application, we discovered a HIGH severity client-side denial of service vulnerability (CVE-2026-44240) in the basic-ftp dependency. The vulnerability existed in version 5.0.5, which was specified in package.json and locked in package-lock.json. This flaw created a critical attack surface: any application using basic-ftp to connect to untrusted or compromised FTP servers could be crashed by a malicious server sending specially crafted FTP responses.

The issue wasn't in the application code itself—it was in a third-party dependency that handles the low-level FTP protocol parsing. This is a common but often overlooked security risk: vulnerabilities in transitive dependencies can silently compromise production systems. The specific problem lay in how basic-ftp 5.0.5 parsed multiline FTP responses, a core part of the FTP protocol used for commands like LIST (directory listings) and HELP.

The Vulnerability Explained

What is an Unterminated Multiline FTP Response Attack?

The FTP protocol (RFC 959) specifies how servers communicate with clients. For responses spanning multiple lines, the protocol requires a specific termination pattern. A typical multiline FTP response looks like this:

211-Features:
 MDTM
 REST STREAM
 TVFS
 UTF8
 AUTH TLS
 PBSZ
 PROT
211 End

The key detail: the response must terminate with a line matching the pattern [code] [text] where [code] is the same numeric code that started the response (211 in this example), preceded by a dash on intermediate lines.

The Vulnerability: basic-ftp 5.0.5 failed to properly validate that multiline responses actually terminated. If an attacker controlled the FTP server or performed a man-in-the-middle attack, they could send:

211-Features:
 MDTM
 REST STREAM
 (continues indefinitely without proper termination...)

Or worse:

211-Feature1
211-Feature2
211-Feature3
(no terminating line with space after code)

How the Attack Works

When the basic-ftp parser encountered an unterminated multiline response:

  1. Infinite Loop: The parser would continue reading lines indefinitely, waiting for the termination marker that never arrives
  2. Memory Exhaustion: Each line is buffered in memory, causing the Node.js process to consume increasing amounts of RAM
  3. CPU Starvation: The parsing loop consumes CPU cycles without making progress
  4. Application Crash: The Node.js process eventually runs out of memory or hits resource limits, causing the entire application to crash

This is particularly dangerous because:
- Silent Failure: The application doesn't receive a clear error—it just hangs and dies
- Cascading Impact: If the FTP client is a service used by other components, the crash propagates
- DoS from Untrusted Servers: Any application connecting to an FTP server outside its control is vulnerable

Real-World Attack Scenario

Imagine an application that:
1. Connects to a customer-provided FTP server to download files
2. Uses basic-ftp 5.0.5 to list directories
3. A malicious customer or compromised server responds with unterminated multiline data

The application's Node.js process crashes, taking down the entire service. An attacker doesn't need code execution—just the ability to respond to FTP commands.

The Fix

The fix involved upgrading basic-ftp from version 5.0.5 to 5.3.1. Let's examine what changed:

Before (package.json - Vulnerable)

{
  "dependencies": {
    "basic-ftp": "^5.0.5"
  }
}

After (package.json - Fixed)

{
  "dependencies": {
    "basic-ftp": "^5.3.1"
  }
}

Package Lock Changes

The package-lock.json was updated to reflect the new version:

- "basic-ftp": "^5.0.5",
+ "basic-ftp": "^5.3.1",

And the integrity hash changed, indicating the package contents were modified:

- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
- "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz",
+ "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==",

What basic-ftp 5.3.1 Fixed

While the specific internal code changes aren't visible in the dependency upgrade diff, the security advisory for CVE-2026-44240 indicates that version 5.3.1 implemented:

  1. Proper Termination Detection: The multiline response parser now strictly validates that responses end with the correct termination pattern (code followed by space)
  2. Resource Limits: Added maximum limits on:
    - Response size (preventing unbounded memory allocation)
    - Number of lines in a multiline response
    - Timeout thresholds for receiving complete responses
  3. Robust Error Handling: Malformed responses now trigger explicit errors rather than infinite loops

The fix ensures that if an FTP server sends an unterminated or malformed multiline response, the client:
- Detects the anomaly quickly
- Throws a clear error
- Allows the application to handle the failure gracefully
- Never enters an infinite loop or exhausts resources

Prevention & Best Practices

1. Keep Dependencies Updated

  • Regularly audit your package.json and package-lock.json for outdated packages
  • Use tools like npm audit to identify vulnerable dependencies
  • Automate dependency updates with tools like Dependabot or Renovate

2. Validate Protocol Responses

When implementing protocol parsers (FTP, SMTP, HTTP, etc.):
- Always validate against the protocol specification
- Implement maximum limits on response size and line counts
- Set timeouts on operations that wait for responses
- Treat untrusted servers as hostile

3. Use Security Scanners

  • Trivy: Scans dependencies for known CVEs (this vulnerability was flagged by Trivy)
  • npm audit: Built-in vulnerability scanning
  • Snyk: Continuous vulnerability monitoring
  • OWASP Dependency-Check: Identifies known vulnerable components

4. Defense in Depth

Even with patched dependencies:
- Implement application-level timeouts on FTP operations
- Monitor resource consumption (memory, CPU) for anomalies
- Use network segmentation to limit which servers your application can connect to
- Run Node.js processes with resource limits (memory caps, CPU throttling)

5. Protocol-Specific Hardening

For FTP specifically:
- Prefer SFTP or other modern protocols when possible
- Validate that FTP servers are in your control or from trusted sources
- Implement connection timeouts
- Log all FTP interactions for audit purposes

Key Takeaways

  • Never assume third-party parsers are robust: Even well-maintained libraries can have protocol parsing vulnerabilities. The basic-ftp 5.0.5 flaw existed in core FTP response handling.
  • Multiline protocol responses require strict validation: The FTP protocol's multiline format is deceptively complex. Proper termination detection is critical to prevent infinite loops.
  • Client-side DoS from untrusted servers is a real threat: Applications connecting to customer-provided or internet-facing FTP servers face this risk. Resource limits and timeouts are essential.
  • Dependency updates fix more than features: Version bumps often include critical security patches. The jump from 5.0.5 to 5.3.1 wasn't just bug fixes—it was a security hardening.
  • Automated vulnerability detection saves lives: Trivy caught this vulnerability in the dependency tree. Integrate security scanning into your CI/CD pipeline to catch these issues before they reach production.

How Orbis AppSec Detected This

Source: FTP server responses (untrusted input from the network)

Sink: The multiline response parser in basic-ftp 5.0.5 (node_modules/basic-ftp/dist/Parser.js - specific line numbers vary by installation)

Missing Control:
- No maximum limit on multiline response length
- No timeout on waiting for response termination
- Insufficient validation that responses actually terminated with the correct pattern

CWE: CWE-400 (Uncontrolled Resource Consumption / Denial of Service)

Fix: Upgrade basic-ftp from 5.0.5 to 5.3.1, which implements proper multiline response validation, resource limits, and timeout handling.

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 demonstrates a critical but often overlooked attack surface: protocol parsing vulnerabilities in third-party dependencies. While the application code itself was secure, a flaw in how basic-ftp 5.0.5 handled FTP responses created a denial of service vector that could crash the entire service.

The fix—upgrading to basic-ftp 5.3.1—was straightforward but essential. It illustrates why security practices must include:

  1. Regular dependency audits to identify vulnerable versions
  2. Automated security scanning to catch these issues before production
  3. Timely updates to apply security patches
  4. Defense-in-depth with application-level safeguards (timeouts, resource limits)

For any Node.js application using FTP, SMTP, or other protocol clients, this vulnerability serves as a reminder: always validate that your dependencies are up-to-date and that you're using security scanning tools to catch vulnerabilities in your supply chain.


References

Frequently Asked Questions

What is a client-side denial of service vulnerability in FTP clients?

It's a flaw where a malicious or compromised FTP server can crash or hang the client by sending malformed protocol responses that the client fails to handle safely, consuming excessive resources or entering infinite loops.

How do you prevent unterminated response attacks in Node.js FTP clients?

Validate all protocol responses against the RFC specification, implement timeouts on response parsing, set maximum limits on response size and line counts, and keep dependencies updated to patch known issues.

What CWE is this client-side DoS vulnerability?

CWE-400 (Uncontrolled Resource Consumption / Uncontrolled Loop), which describes failures to properly limit resource consumption when processing untrusted input.

Is input validation enough to prevent this type of DoS?

Partial—you need both strict protocol parsing (validating response format), resource limits (max response size, timeout thresholds), and proper error handling to completely mitigate this class of attack.

Can static analysis detect unterminated response parsing vulnerabilities?

Yes, modern security scanners like Trivy can detect known vulnerable versions of dependencies, and SAST tools can flag infinite loops in parsing logic, though protocol-specific semantic analysis is most effective.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #223

Related Articles

high

How Arbitrary Code Execution via Template Imports Happens in JavaScript (lodash) and How to Fix It

A high-severity arbitrary code execution vulnerability (CVE-2026-4800) was discovered in lodash's template function, specifically in how it handles the `imports` option with untrusted input. The fix upgrades lodash from version 4.17.21 to 4.18.0 in the project's `package.json` and `yarn.lock`, eliminating the attack surface where crafted template imports could execute arbitrary code on the server.

high

How IPv4-mapped IPv6 addresses bypass rate limiting in Express.js and how to fix it

A critical vulnerability in express-rate-limit versions prior to 8.2.2 allowed attackers to bypass per-client rate limiting on dual-stack servers by exploiting incorrect IPv6 subnet masking. When IPv4 clients connected through IPv4-mapped IPv6 addresses (like ::ffff:192.0.2.1), the library failed to properly identify unique clients, enabling unlimited requests that could lead to denial of service. The fix upgrades express-rate-limit to 8.2.2 and its dependency ip-address to 10.1.0, implementing

high

How Denial of Service via Unbounded Brace Expansion happens in Node.js and how to fix it

The brace-expansion library in Node.js contained a critical denial-of-service vulnerability where specially crafted input could trigger unbounded array expansion, consuming all available memory and crashing the process. This vulnerability affected multiple versions across the library's version branches. The fix upgrades brace-expansion to patched versions that implement strict limits on intermediate array sizes.

high

How Remote Memory Exhaustion Happens in Rust QUIC Implementations and How to Fix It

A high-severity vulnerability in `quinn-proto` allowed remote attackers to exhaust server memory by sending carefully crafted out-of-order QUIC stream data, triggering unbounded buffer growth during reassembly. The fix upgrades `rustls-webpki` from `0.103.10` to `0.103.13` in `Cargo.lock`, closing a related denial-of-service primitive that could be chained with the stream reassembly weakness. Together, these changes harden the QUIC stack against memory exhaustion attacks that require no authenti

high

How Authentication Bypass happens in Next.js App Router with Turbopack and how to fix it

A critical authentication bypass vulnerability (CVE-2026-64642) was discovered in Next.js versions prior to 16.2.11, specifically affecting App Router applications using Turbopack with a single locale configuration. This vulnerability allowed attackers to bypass middleware and proxy protections, potentially gaining unauthorized access to protected routes and resources that should have been secured by authentication checks.

high

How GitHub Actions Shell Injection happens in YAML workflows and how to fix it

A GitHub Actions workflow in `reusable-workflow-input-must-declare-type.yaml` was directly interpolating `${{ inputs.constraints }}` inside a `run:` shell step, creating a shell injection vulnerability. An attacker who controls the workflow input could inject arbitrary shell commands into the runner, potentially stealing secrets and source code. The fix moves the untrusted value into an intermediate environment variable, breaking the injection path entirely.