CVE-2026-126346
### Summary Client.login() calls FTPContext.send() from inside the control-socket data event handler. send() throws on CR, LF or NUL, and nothing catches the throw. A password containing \r\n therefore raises an uncaught exception and terminates the whole Node.js process. It does not reject the returned promise. Any application that passes untrusted input as the FTP password can be crashed remotely with one request. The same pattern exists in the REST/RETR path of downloadTo() when the remote path contains control characters. ### Details The CRLF guard (FTPContext.send, src/FtpContext.ts ~L233) correctly refuses to send commands containing \r, \n or \0: ```ts send(command: string) { if (/[\r\n\0]/.test(command)) { throw new Error(`Invalid command: Contains control characters. (${command})`); } ``` That works when send() is called from handle(), because it runs inside a Promise executor and the throw becomes a rejection. But in two places send() runs inside a response handler, which is called synchronously from the socket’s data event: Client.login() (src/Client.ts ~L246-248): after the server answers 331 to USER, the handler calls this.ftp.send("PASS " + password). The USER command was already sent and is valid, so the password is only checked at this point. The call chain is socket.on("data") → _onControlSocketData → _passToHandler → responseHandler → send() → throw. No try/catch exists anywhere in that chain, so it becomes an uncaughtException. downloadTo() (src/transfer.ts ~L368-370): when startAt > 0, the initial command is REST n, which contains no user-controlled text. When the server answers 350, the handler calls config.ftp.send("RETR " + config.remotePath). This remotePath was never checked before. A path with a control character throws in the data handler in the same way. (Found by code reading, not reproduced.) Because the exception happens during data event dispatch, it can’t be handled with try/catch or .catch() around client.acces
Properties
- Severity
- medium
- Summary
- basic-ftp: Uncaught exception crashes the Node.js process when a password (or resumed-download path) contains CR/LF
- Nvd fetched at
- 2026-11-14T00:40:25.638091+00:00
- Epss score
- 0.01672
- Cvss severity
- MEDIUM
- Cvss score
- 5.9
- Retrieved at
- 2026-11-14T00:51:03+00:00
- Ghsa published
- 2026-11-12T22:23:50Z
- Source url
- https://github.com/advisories/GHSA-r4jh-29pc-gfqr
- Ghsa updated
- 2026-11-12T22:23:50Z
- Ghsa id
- GHSA-r4jh-29pc-gfqr
- Last source
- FIRST EPSS
- Score
- 5.9
- Cvss version
- 3.1
- Cve id
- CVE-2026-126346
- Cvss vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H
- First seen by Signal
- 2026-11-13T00:03:24+00:00
- Name
- CVE-2026-126346
- Is ghsa only
- false
- Vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H
Related Entities (4)
HAS_WEAKNESS (2)
AFFECTS (1)
VULNERABLE_TO (1)
Related research
Explore deeper with Ninja Signal's threat intelligence graph