Oct 1, 2026·6 min read·6 visits
Unanchored regular expressions and adjacent variable-length capture groups in basic-ftp's Unix and DOS directory-listing parsers allow a malicious FTP server to cause CPU exhaustion and freeze Node.js client applications.
A highly critical Regular Expression Denial of Service (ReDoS) vulnerability in basic-ftp, an FTP client library for Node.js. In versions prior to 6.2.1, a malicious or compromised FTP server can exploit this vulnerability to force the FTP client to consume quadratic CPU time during directory parsing. This issue blocks the single-threaded Node.js event loop, freezing the application process and leading to a complete Denial of Service (DoS).
basic-ftp is a widely used Node.js library designed to handle FTP and FTPS connections. The library includes directory parsing mechanisms that process directory listings returned by FTP servers. Because FTP servers represent directory layouts as plain text files, the client library must parse these outputs to identify file attributes like permissions, size, and modification dates.
The vulnerability identified as CVE-2026-102990 is a Regular Expression Denial of Service (ReDoS) vulnerability categorized under CWE-1333. It resides within the directory-listing parser modules src/parseListUnix.ts and src/parseListDOS.ts. A compromised or malicious FTP server can exploit this vulnerability to trigger catastrophic backtracking or unanchored matching, causing the Node.js process to consume maximum CPU resources.
Because Node.js is single-threaded, a high-complexity regular expression match blocks the event loop. The entire application becomes unresponsive to other concurrent requests, resulting in a Denial of Service. The vulnerability can be triggered without authentication if the application is configured to connect to untrusted servers.
The core issue in src/parseListUnix.ts involves the regular expression used to parse Unix-style directory listings. The expression RE_LINE defines optional capturing groups for the owner and group names. These capturing groups use the sub-patterns to accommodate names containing spaces.
Because these two optional capturing groups are directly adjacent, the regular expression engine is forced to evaluate multiple combinations when a line fails to match the subsequent required patterns. Specifically, when the parser encounters a line with a long sequence of space-separated tokens that fails to match the mandatory size field, the engine attempts to backtrack. It evaluates every permutation of how the tokens can be distributed between the owner and group fields.
This leads to catastrophic backtracking, which has a quadratic complexity relative to the number of space-separated tokens. The second flaw is located in src/parseListDOS.ts where the DOS line regular expression is not anchored at the start of the line. When a non-matching line is parsed, the engine slides along the line and attempts to evaluate the pattern at each character index, resulting in another quadratic complexity path.
Comparing the vulnerable implementation with the patched version reveals how the catastrophic backtracking was resolved. In the vulnerable Unix parser, the owner and group name sub-patterns used the unbounded Kleene star operator. This allowed an arbitrary number of space-separated words to match either field.
// Vulnerable Unix Parser RE_LINE snippet
const RE_LINE = new RegExp(
"([bcdelfmpSs-])"
+ "(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]?)))\\+?"
+ "\\s*"
+ "(\\d+)"
+ "\\s+"
+ "(?:(\\S+(?:\\s\\S+)*?)\\s+)?"
+ "(?:(\\S+(?:\\s\\S+)*)\\s+)?"
+ "(\\d+(?:,\\s*\\d+)?)"
)The patch resolves this by replacing the unbounded Kleene star with a bounded range and adding a start-of-line anchor. The bounded range limits the backtracking state space by permitting a maximum of eight space-separated tokens for the owner and group names. This small constant factor prevents exponential or quadratic execution times on non-matching strings.
// Patched Unix Parser RE_LINE snippet
const RE_LINE = new RegExp(
"^[\\s\\d]*"
+ "([bcdelfmpSs-])"
+ "(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]?)))\\+?"
+ "\\s*"
+ "(\\d+)"
+ "\\s+"
+ "(?:(\\S+(?:\\s\\S+){0,7}?)\\s+)?"
+ "(?:(\\S+(?:\\s\\S+){0,7})\\s+)?"
+ "(\\d+(?:,\\s*\\d+)?)"
)The DOS parser was similarly hardened by adding the start-of-line anchor to the beginning of RE_LINE. This ensures the engine fails immediately on non-matching lines instead of sliding along the line and retrying the match at every position.
An attacker must host or compromise an FTP server and wait for a vulnerable basic-ftp client to connect. When the client executes the list method, the server returns a crafted directory listing response. The listing contains a malicious line designed to trigger the catastrophic backtracking behavior.
The exploit payload consists of a single long line containing dozens of space-separated characters, ending with a character that fails the subsequent numeric constraint. For example, sending a line starting with valid Unix permissions followed by a long sequence of space-separated tokens and a trailing letter that is not a digit will trigger the vulnerability. The trailing letter prevents the regular expression from matching the final mandatory numeric size field, forcing the engine into a backtracking loop.
To ensure the client selects the vulnerable Unix parser, the malicious server includes a valid Unix directory entry as the final line of the directory listing. The client's heuristic parser selection logic looks at the final non-blank line of the input to determine which parser to apply to the entire dataset. This guarantees that the crafted payload line is evaluated using the vulnerable Unix regular expression.
The impact of CVE-2026-102990 is a complete Denial of Service on the affected Node.js process. Because the Node.js runtime utilizes a single-threaded event loop, any synchronous operation that blocks the thread prevents all other events, timers, and incoming network requests from being processed. This halts the entire application server.
If the application runs inside a containerized orchestrator such as Kubernetes, the sustained high CPU utilization may trigger horizontal scaling or cause health check endpoints to time out. The container orchestrator may then attempt to restart the container repeatedly, leading to a crash loop and prolonged service unavailability.
No unauthorized file access, privilege escalation, or data exfiltration is directly associated with this vulnerability. However, the ease of triggerability and the low level of attack complexity make this a high-availability impact issue. The CVSS v4.0 base score is calculated at 8.2 with an impact of high availability degradation.
The primary remediation path is to upgrade the basic-ftp package to version 6.2.1 or later. The update applies the required regular expression anchors and replaces the unbounded operators with bounded intervals. This prevents catastrophic backtracking and restores linear parsing performance.
If an immediate upgrade is not feasible, several temporary mitigation strategies can be employed. Applications should avoid connecting to untrusted or user-supplied FTP server addresses. Implementing strict network-level egress filtering can limit outbound connections to verified, trusted FTP endpoints.
Additionally, running the Node.js application within a child process or a worker thread can isolate the directory parsing logic. While a worker thread may still experience high CPU utilization during exploitation, it will prevent the main application thread and the primary event loop from freezing entirely.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
basic-ftp Patrick Juchli | < 6.2.1 | 6.2.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1333 |
| Attack Vector | Network |
| CVSS v4.0 | 8.2 (High) |
| EPSS Score | 0.00507 |
| Impact | Availability (High) |
| Exploit Status | PoC Available |
| KEV Status | Not Listed |
The product uses a regular expression that can take a very long time to evaluate against certain input strings, resulting in resource exhaustion.
An authorization bypass and path traversal vulnerability exists in the SiYuan knowledge workspace platform. The vulnerability is located in the '/api/file/getUniqueFilename' endpoint inside the 'github.com/siyuan-note/siyuan/kernel' package. Under default configurations, this route is exposed to users who satisfy basic authentication middleware checks, which includes anonymous readers in publish mode. By supplying unvalidated absolute paths, remote attackers can verify the existence of files and directories across the host operating system, establishing a high-fidelity file existence oracle.
An uncontrolled resource consumption vulnerability in the russh library allows remote authenticated attackers to exhaust server memory (heap) by flooding channel open requests during a stalled key re-exchange (rekeying) process, causing a denial of service via Out-of-Memory (OOM) termination.
A critical memory handling vulnerability exists in the pageant crate, a workspace component of the Rust-based russh SSH client library, during communication with the PuTTY Pageant SSH agent on Windows systems. Prior to version 0.2.3, the library's shared memory parsing logic blindly trusted a peer-controlled, 32-bit big-endian response length field. This allows local attackers running within the same user session to trigger out-of-bounds reads or execute an out-of-memory crash of the client application.
A validation bypass vulnerability exists in Fastify web framework prior to version 5.12.2. The flaw stems from shallow normalization of header validation schemas, which fails to lowercase nested or conditional schema rules (like JSON Schema dependencies or dependentRequired) defined in mixed or canonical casing. Consequently, because Node.js normalizes incoming HTTP request headers to lowercase, the compiled validator fails to match these headers against the un-normalized mixed-case schema triggers, silently skipping conditional checks and allowing unauthenticated attackers to bypass authorization or security headers.
CVE-2026-84469 is a high-severity request validation bypass vulnerability in the Fastify Node.js web framework. In versions prior to 5.12.2, Fastify uses loose truthiness checks to decide whether to compile request schemas. When a component (such as the body) is explicitly configured with a boolean 'false' schema—which under JSON Schema Draft 7 acts as a 'deny-all' constraint—Fastify's internal logic evaluates this as a falsy value and skips compilation entirely. This allows unauthenticated remote attackers to send arbitrary payloads to these endpoints, bypassing validation checks and directly executing backend route handlers.
An authentication bypass vulnerability in the Fastify web framework allows remote attackers to access private custom not-found handlers by submitting requests with malformed URLs. This bypasses the typical request lifecycle and its associated authorization hooks.