Skip to content

fix(deps): pin basic-ftp to 5.3.1 to fully clear CVE-2026-39983 and 3 sibling HIGH advisories#2227

Open
time-attack wants to merge 2 commits into
garrytan:mainfrom
time-attack:fix/basic-ftp-cve-2026-39983
Open

fix(deps): pin basic-ftp to 5.3.1 to fully clear CVE-2026-39983 and 3 sibling HIGH advisories#2227
time-attack wants to merge 2 commits into
garrytan:mainfrom
time-attack:fix/basic-ftp-cve-2026-39983

Conversation

@time-attack

Copy link
Copy Markdown

basic-ftp reaches the dependency tree only transitively:

puppeteer-core → @puppeteer/browsers → proxy-agent → pac-proxy-agent → get-uri → basic-ftp

Versions ≤ 5.3.0 carry four HIGH advisories, all fixed in 5.3.1:

  • GHSA-chqc-8p9q-pq6q (CVE-2026-39983) — FTP command injection via CRLF
  • GHSA-6v7q-wjvx-w8wg — incomplete CRLF protection (USER/PASS + MKD bypass)
  • GHSA-rpmf-866q-6p89 — DoS via unbounded multiline control-response buffering
  • GHSA-rp42-5vxx-qpwr — DoS via unbounded memory in Client.list()

Fix

Pin via a bun overrides entry so every basic-ftp in the tree resolves to 5.3.1 (including get-uri's nested copy), rather than adding a phantom direct dependency. bun audit goes from 4 basic-ftp HIGH advisories to 0 (repo total 37 → 33, HIGH 13 → 9). 5.3.1 stays within get-uri's ^5.0.2 range and avoids the 6.x major bump.

Adds test/basic-ftp-security-pin.test.ts — a deterministic, offline tripwire that fails if any resolved basic-ftp in bun.lock (including nested paths like get-uri/basic-ftp) is below 5.3.1.

Why this supersedes #2205

#2205 bumps basic-ftp to 5.2.1 as a direct dependency. Verified locally: after that change, bun keeps get-uri/basic-ftp@5.2.0 nested, the root 5.2.1 copy is unused (gstack imports nothing from basic-ftp), and bun audit still reports all four HIGH advisories unchanged. 5.2.1 would also only address 1 of the 4 (the incomplete-CRLF follow-up needs 5.2.2; the two DoS advisories need 5.3.1).

Verification

  • Clean bun install → only basic-ftp@5.3.1 in the tree; bun audit reports zero basic-ftp advisories.
  • Live FTP server (ftp-srv) round-trip on 5.3.1: list / downloadTo / uploadFrom / cd / pwd / size all work identically to 5.2.0 on legitimate paths.
  • Security behavior confirmed: a CRLF path (cd("nowhere\r\nDELE SENTINEL.txt")) that deletes a file on 5.2.0 is rejected client-side on 5.3.1 ("Contains control characters").
  • get-uri@6.0.5 fetches an ftp:// URI on the overridden 5.3.1 — the exact operation pac-proxy-agent performs.
  • Free test suite: no new failures.

🤖 Generated with Claude Code

test22345 and others added 2 commits July 10, 2026 13:58
…bling HIGH advisories

basic-ftp reaches the tree only transitively:
  puppeteer-core > @puppeteer/browsers > proxy-agent > pac-proxy-agent > get-uri > basic-ftp

Versions <= 5.3.0 carry four HIGH advisories, all fixed in 5.3.1:
- GHSA-chqc-8p9q-pq6q (CVE-2026-39983) FTP command injection via CRLF
- GHSA-6v7q-wjvx-w8wg incomplete CRLF protection (USER/PASS + MKD bypass)
- GHSA-rpmf-866q-6p89 DoS via unbounded multiline control-response buffering
- GHSA-rp42-5vxx-qpwr DoS via unbounded memory in Client.list()

Pin via a bun `overrides` entry rather than a phantom direct dependency.
Overriding forces every basic-ftp in the tree to 5.3.1, including get-uri's
nested copy; `bun audit` then reports zero basic-ftp advisories (total 37 -> 33,
HIGH 13 -> 9). A direct-dependency bump leaves get-uri/basic-ftp at the
vulnerable version and audit still flags all four.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parses package.json overrides + every resolved basic-ftp specifier in bun.lock
(including nested paths like get-uri/basic-ftp) and fails if any is below 5.3.1.
Deterministic and offline. Fires on the pre-fix tree (basic-ftp@5.2.0) and would
also catch a direct-dependency-only bump that leaves a nested vulnerable copy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jul 10, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

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.

2 participants