Skip to content

Bump transitive basic-ftp to a patched version to remediate CVE-2026-27699#682

Merged
nirinchev merged 2 commits intomainfrom
copilot/fix-path-traversal-vulnerability
Apr 16, 2026
Merged

Bump transitive basic-ftp to a patched version to remediate CVE-2026-27699#682
nirinchev merged 2 commits intomainfrom
copilot/fix-path-traversal-vulnerability

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

Dependabot flagged basic-ftp for a critical path traversal vulnerability in downloadToDir() (GHSA-5rq4-664w-9x2c / CVE-2026-27699). The vulnerable version (5.0.5) was present transitively via proxy dependencies.

  • What changed

    • Updated lockfile resolution for transitive basic-ftp from 5.0.5 to 5.3.0 (patched range is >=5.2.0).
    • Kept manifests unchanged to minimize impact; this is a lockfile-scoped dependency remediation.
  • Dependency path affected

    • @mongodb-js/devtools-proxy-supportpac-proxy-agentget-uribasic-ftp
  • Reachability Assessment

    • Advisory scope is basic-ftp’s downloadToDir() API.
    • Current transitive usage (via get-uri) uses client.downloadTo(...), not downloadToDir().
    • Assessment: not currently reachable from repository code paths; update is primarily scanner remediation.
    • Confidence: high (specific vulnerable API identified and usage pattern verified).
- "node_modules/basic-ftp": { "version": "5.0.5", ... }
+ "node_modules/basic-ftp": { "version": "5.3.0", ... }

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/devtools-shared/devtools-shared/node_modules/.bin/mocha -gyp sh k/_t�� . che/node-gyp/24.. bin/sh dn't have any #inode -I ode-gyp-bin/noderun prettier --ch�� . ures/include d/packages/node_modules/.bin/node --runtime napi bash -I ode-gyp-bin/sh node (dns block)
  • example.net
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/devtools-shared/devtools-shared/node_modules/.bin/mocha -gyp sh k/_t�� . che/node-gyp/24.. bin/sh dn't have any #inode -I ode-gyp-bin/noderun prettier --ch�� . ures/include d/packages/node_modules/.bin/node --runtime napi bash -I ode-gyp-bin/sh node (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details the Dependabot vulnerability alert you should resolve

<alert_title>Basic FTP has Path Traversal Vulnerability in its downloadToDir() method</alert_title>
<alert_description>The basic-ftp library contains a path traversal vulnerability in the downloadToDir() method. A malicious FTP server can send directory listings with filenames containing path traversal sequences (../) that cause files to be written outside the intended download directory.

Source-to-Sink Flow

1. SOURCE: FTP server sends LIST response
└─> "-rw-r--r-- 1 user group 1024 Jan 20 12:00 ../../../etc/passwd"

2. PARSER: parseListUnix.ts:100 extracts filename
└─> file.name = "../../../etc/passwd"

3. VALIDATION: parseListUnix.ts:101 checks
└─> if (name === "." || name === "..") ❌ (only filters exact matches)
└─> "../../../etc/passwd" !== "." && !== ".." ✅ PASSES

4. SINK: Client.ts:707 uses filename directly
└─> const localPath = join(localDirPath, file.name)
└─> join("/safe/download", "../../../etc/passwd")
└─> Result: "/safe/download/../../../etc/passwd" → resolves to "/etc/passwd"

5. FILE WRITE: Client.ts:512 opens file
└─> fsOpen(localPath, "w") → writes to /etc/passwd (outside intended directory)

Vulnerable Code

File: src/Client.ts:707

protected async _downloadFromWorkingDir(localDirPath: string): Promise<void> {
await ensureLocalDirectory(localDirPath)
for (const file of await this.list()) {
const localPath = join(localDirPath, file.name) // ⚠️ VULNERABLE
// file.name comes from untrusted FTP server, no sanitization
await this.downloadTo(localPath, file.name)
}
}

Root Cause:
- Parser validation (parseListUnix.ts:101) only filters exact . or .. entries
- No sanitization of ../ sequences in filenames

  • path.join() doesn't prevent traversal, fs.open() resolves paths

Impact

A malicious FTP server can:
- Write files to arbitrary locations on the client filesystem
- Overwrite critical system files (if user has write access)
- Potentially achieve remote code execution

Affected Versions

  • Tested: v5.1.0
  • Likely: All versions (code pattern exists since initial implementation)

Mitigation

Workaround: Do not use downloadToDir() with untrusted FTP servers.

Fix: Sanitize filenames before use:

import { basename } from 'path'

// In _downloadFromWorkingDir:
const sanitizedName = basename(file.name) // Strip path components
const localPath = join(localDirPath, sanitizedName)
```</alert_description>

<severity>critical</severity>
<identifiers>GHSA-5rq4-664w-9x2c, CVE-2026-27699</identifiers>
<package>basic-ftp</package>
<ecosystem>npm</ecosystem>
<vulnerable_versions>5.0.5</vulnerable_versions>
<patched_version>5.2.0</patched_version>
<manifest_path>package-lock.json</manifest_path>

<references>
<url>https://github.com/patrickjuchli/basic-ftp/security/advisories/GHSA-5rq4-664w-9x2c</url>
<url>https://nvd.nist.gov/vuln/detail/CVE-2026-27699</url>
<url>https://github.com/patrickjuchli/basic-ftp/commit/2a2a0e6514357b9eda07c2f8afbd3f04727a7cd9</url>
<url>https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.0</url>
<url>https://github.com/advisories/GHSA-5rq4-664w-9x2c</url>
</references>

<agent_instructions>Upgrade dependencies in the relevant packages to address this CVE. If this is a transitive dependency, find the direct dependency that brings it in and attempt to update that one, even if it requires a major version upgrade. If a major version bump is required, make the necessary code changes to adapt to the new API. Only ever use `overrides` in package.json if there's no new version of the direct dependency that pulls in the fixed transitive dependency. Additionally, investigate whether the vulnerability actually impacts user-facing code. When creating a PR, note the outcome of your investigation.</agent_instructions>

<task_instructions>Resolve this alert by updating the affected package to a non-vulnerable version. Prefer the lowest non-vulnerable version (see the patched_version field above) over the latest to minimize breaking changes. Include a Reachability Assessment section in the PR description. Review the alert_description field to understand which APIs, features, or configurations are affected, then search the codebase for usage of those specific items. If the vulnerable code path is reachable, explain how (which files, APIs, or call sites use the affected functionality) and note that the codebase is actively exposed to this vulnerability. If the vulnerable code path is not reachable, explain why (e.g. the affected API is never called, the vulnerable configuration is not used) and note that the update is primarily to satisfy vulnerability scanners rather than to address an active risk. If the advisory is too vague to determine reachability (e.g. 'improper input validation' with no specific API named), state that reachability could not be determined and explain why. Include a confidence leve...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Resolves mongodb-js/devtools-shared alert #155

Copilot AI changed the title [WIP] Fix path traversal vulnerability in basic-ftp Bump transitive basic-ftp to a patched version to remediate CVE-2026-27699 Apr 16, 2026
Copilot AI requested a review from nirinchev April 16, 2026 18:23
@nirinchev nirinchev marked this pull request as ready for review April 16, 2026 18:24
@nirinchev nirinchev enabled auto-merge (squash) April 16, 2026 18:25
@coveralls
Copy link
Copy Markdown

Coverage Status

coverage: 72.424% (-5.9%) from 78.318% — copilot/fix-path-traversal-vulnerability into main

@nirinchev nirinchev merged commit 4340e80 into main Apr 16, 2026
36 checks passed
@nirinchev nirinchev deleted the copilot/fix-path-traversal-vulnerability branch April 16, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants