Changelog
[1.2.4] 2026-08-17 Security (1)
Security
- Prototype pollution through bracket-notation keys in
toObjectParser(src/query-string-parsers.ts:5,:11,:49). Nested keys were walked by assigning into plain{}accumulators, so?__proto__[isAdmin]=1and?constructor[prototype][isAdmin]=1wrote through toObject.prototype. Every object in the page then readsisAdminas"1"— including objects consuming apps use for feature gates and authorization decisions — and the value survives until reload. The input here is a URL, so a crafted link is the entire attack.__proto__,constructorandprototypeare now rejected as key segments, and every accumulator the parser creates usesObject.create(null), so no nesting level can resolve to a prototype in the first place. Ordinary keys are unaffected.
[1.2.3] 2026-05-26 Fixed (3) · Added (5)
Fixed
toStringParsernow percent-encodes values. Values containing&,=, or other reserved characters are run throughencodeURIComponentso the output round-trips cleanly throughparse. Keys remain unencoded so thekey[sub]/key[]bracket syntax keeps working. Fix atsrc/query-string-parsers.ts:55-60; previously-skipped tests insrc/__tests__/serialize.test.ts(“percent-encoding”) are now enabled.toStringParsernow serializesnullas the literalnull. Avalue === nullshort-circuit runs before thetypeof === "object"branch so the key no longer disappears. Fix atsrc/query-string-parsers.ts:55; the previously-skipped serialize test now passes. Note: this is an asymmetric round-trip —parse("v=null")yields{ v: "null" }(string) because the parser has no way to distinguish typed null from the four characters of"null".toObjectParserno longer writes the string"undefined"for a key with no=. Whenpair[1]isundefined, the value is now set to""instead of being fed intodecodeURIComponent. Fix atsrc/query-string-parsers.ts:14; the previously-skipped parse test now passes.
Added
- Test suite. 90 vitest unit tests under happy-dom across
parse,serialize, the lower-levelparsers, and the browser-boundall/get/update/toStringmethods. Total: 90 passing, 0 skipped. - AI kit.
llms.txt,llms-full.txt, and askills/folder (README,overview,parse,serialize,recipes) for tool-assisted development. - CI. GitHub Actions workflow: Node 18/20/22 on Ubuntu, plus Node 20 on Windows.
vitest.config.tsbased on the @mongez/atom pattern. happy-dom environment (becausequeryString.all()defaults towindow.location.searchandqueryString.update()callshistory.replaceState), self-detecting sibling-alias helper (currently no aliases — kept for future use).package.jsonfields. Realdescription(was a stub flagged during workspace migration), expandedkeywords(querystring,query-string,url,parse,serialize,stringify,search-params,nested,mongez),sideEffects: false,scripts.test,scripts.test:watch, and devDependencies forhappy-dom,typescript,vitest. Version bumped from0.0.1(stub) to1.0.0.
Tests
90 passing, 0 skipped