Skip to content

fix(security): sanitise verifyUrl URL + pin undici override - #70

Merged
nxn94 merged 2 commits into
mainfrom
dev
Sep 29, 2026
Merged

nxn94 merged 2 commits into
mainfrom
dev

Conversation

@nxn94

@nxn94 nxn94 commented Sep 29, 2026

Copy link
Copy Markdown
Owner

What

Two security fixes (one true, one false-positive-class-but-preventative).

fix(security): sanitise verifyUrl URL through new URL() + require https

Resolves CodeQL alert #37 (js/file-access-to-http in unified-downloader.js @ line 283). The HEAD-probe took a URL string that originated from a file read (cache.js or config.js download_urls) and passed it straight into fetch() — the taint flow was real even though the cache file is operationally only written by this module from successful resolver round-trips.

Fix: parse the URL through the WHATWG URL parser (new URL()) and require protocol === "https:", then pass parsed.toString() to fetch. new URL() is the CodeQL-recognised sanitiser for this query — the file → fetch edge becomes string → parsed URL → re-stringified URL → fetch, and the protocol gate blocks any non-https scheme that might have landed there via a tampered cache file or a misauthored config.json entry.

Verified: re-running CodeQL on the dev branch reports zero open alerts for this file (was 1 before this fix).

fix(deps): pin undici override >= 7.29.1 (closes Dependabot alert #12)

CVE-2026-85024 / GHSA-3wwx-pv78v: undici WebSocket client DoS via malformed DEFLATE block (CWE-248 uncaught exception, CVSS 5.9). We do not use new WebSocket() directly, but cheerio 1.2.0 pulls in undici and resolved to the vulnerable 7.29.0.

Pin undici to ^7.29.1 via package.json overrides — same pattern already used for brace-expansion, minimatch, and js-yaml (the latter closes prior Dependabot alert #10). Lockfile now resolves undici to 7.30.0 (the patched line).

Dependabot PR #69

This PR is independent of #69 (Dependabot fast-uri 3.1.6 → 3.1.8 for CVE-2026-84394 / GHSA-58mr-gqgx-xq4g, CVSS 7.5). #69 will be merged onto main after this branch lands.

Test plan

Docs

  • AGENTS.md Repo quirks: new bullet on the verifyUrl sanitisation contract
  • docs/troubleshooting.md: new "verifyUrl rejects the cached URL" entry covering operator-visible behaviour

Backward compatibility

None for legitimate URLs (all cached URLs are written by saveCachedUrl() from apkeep / apkmirror-api / apkmirror / patches.json sources — all https://). Hand-edited config.json download_urls entries using non-https will now be rejected; the resolver will fall through to the next source and re-write the cache.

nxn (via Hermes) added 2 commits September 29, 2026 21:06
Resolves CodeQL alert #37 (js/file-access-to-http in
unified-downloader.js @ 283). The HEAD-probe took a URL string that
originated from a file read (cache.js or config.js download_urls)
and passed it straight into fetch() — the taint flow was real
even though the cache file is operationally only written by this
module from successful resolver round-trips.

Fix: parse the URL through the WHATWG URL parser (new URL()) and
require protocol === 'https:', then pass parsed.toString() to
fetch. new URL() is the CodeQL-recognised sanitiser for this query
— the file -> fetch edge becomes string -> parsed URL ->
re-stringified URL -> fetch, and the protocol gate blocks any
non-https scheme that might have landed there via a tampered cache
file or a misauthored config.json entry.

Tests:
  - unified-downloader-timers.test.js: 4 new cases covering
    http://, file://, malformed, and the canonical https: accept
    path. fetch is asserted NOT to have been called for any
    non-https / malformed input.
  - fallback-chain.test.js: replaced the file:// cache fixture
    URL with https://example.invalid/... (verifyUrl now rejects
    file://). Replaced the real-curl spawnImpl with a shim that
    copies the placeholder fixture so the test no longer depends
    on curl's file:// support or network egress for example.invalid.

Docs:
  - AGENTS.md 'Repo quirks': new bullet on the verifyUrl
    sanitisation contract.
  - docs/troubleshooting.md: new 'verifyUrl rejects the cached URL'
    section covering the operator-visible behaviour (non-https
    URLs now log a rejection and the resolver falls through).
CVE-2026-85024 / GHSA-3wwx-pv78v: undici's WebSocket client crashes
the entire Node.js process on a malformed DEFLATE block after a
permessage-deflate size limit (CWE-248 uncaught exception, CVSS 5.9).

We don't use undici's WebSocket client directly (no new WebSocket()
call in our source). cheerio 1.2.0 depends on undici ^7.19.0 and
its npm-published resolution landed on the vulnerable 7.29.0. Pin
undici to ^7.29.1 via package.json overrides, same pattern already
used for brace-expansion, minimatch, and js-yaml (closes prior
Dependabot alerts). Lockfile now resolves undici to 7.30.0 (the
patched line is >= 7.29.1).

Dependabot opened a separate PR (#69) to fix the related fast-uri
CVE-2026-84394; that will be merged onto main after this branch
lands.
@nxn94
nxn94 merged commit c87c9cd into main Sep 29, 2026
4 checks passed
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.

1 participant