Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-httpinunified-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 requireprotocol === "https:", then passparsed.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.1viapackage.jsonoverrides— same pattern already used forbrace-expansion,minimatch, andjs-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
npm run check(lint + 509 tests + validate:config + validate:agent-docs + check:readme) — greenverifyUrltest cases (http://, file://, malformed, canonical https:)Docs
AGENTS.mdRepo quirks: new bullet on the verifyUrl sanitisation contractdocs/troubleshooting.md: new "verifyUrlrejects the cached URL" entry covering operator-visible behaviourBackward compatibility
None for legitimate URLs (all cached URLs are written by
saveCachedUrl()fromapkeep/apkmirror-api/apkmirror/patches.jsonsources — allhttps://). Hand-editedconfig.jsondownload_urlsentries using non-https will now be rejected; the resolver will fall through to the next source and re-write the cache.