Evidenceufo-282
Usage of default-prototype Object for URL params results in parsing problems
ufo#282, at commit e383832. A closed issue from a repository Credda did not choose.
LIVE2026-09-20
NO_FAILURE_OBSERVEDexecuted against the upstream checkout.
- Outcome
- NO_CHANGE_REQUIRED
- Wall time
- 61.9s
- Checks
- 3 passed of 5 applicable
RECORDED
NOT_GRADEDgraded from the transcript committed with this case.
- Outcome
- not recorded
- Checks
- none run
01The signal
The report, exactly as it was filed.
Nothing paraphrased or cleaned up. The mess is the thing under test.
Usage of default-prototype Object for URL params results in parsing problems
### Environment
Node v23.10.0, `ufo` version 1.5.4.
### Reproduction
```js
> ufo.getQuery("http://foo.com/?toString=a")
{ toString: [ [Function: toString], 'a' ] }
```
### Describe the bug
The accumulator object used during query parsing (initialized [here](https://github.com/unjs/ufo/blob/main/src/query.ts#L34)), is a regular JavaScript Object. This means that it all the default Object keys are valid keys:
```js
> x = {};
{}
> x.<tab complete>
x.__proto__ x.constructor x.hasOwnProperty x.isPrototypeOf x.propertyIsEnumerable
x.toLocaleString x.toString x.valueOf
```
As regular key-accessing is used, the prototype chain is followed, hence, the check [here](https://github.com/unjs/ufo/blob/main/src/query.ts#L48) will not be undefined for those keys, and [this](https://github.com/unjs/ufo/blob/main/src/query.ts#L53) assignment logic will be followed.
In other words, while there is a check for `__proto__` and `constructor` to prevent prototype pollution (I presume), this does not solve the problem of accessing other keys in the object's prototype. A good solution would be to use `Object.create(null)` instead of `{}` to initialize `object`.
### Additional context
_No response_
### Logs
```sh
```- Repository
- unjs/ufo
- Issue
- #282
- Commit
- e383832e6aa1253a0b423cbb588bc0716f274f83
- Why this commit
- The first parent of the fix commit 4d024df0134e2484b1e22ba17a08fea31e90de92, which GitHub binds to this issue via CLOSED_EVENT_PR. Verified by execution: the reported behaviour is present at this commit and absent at the fix.
- How the text was obtained
- Fetched verbatim via the GitHub GraphQL API. Title on the first line, body unmodified below it. Nothing was paraphrased, cleaned up, or supplemented.
- Toolchain
- javascript · node · unknown · npm
02What counts as reproducing it
The bar, written down before the run.
- Symptom
- ufo.getQuery("http://foo.com/?toString=a") produces { toString: [ [Function: toString], 'a' ] }; the fix makes it produce C <[Object: null prototype] {}> { toString: 'a' }.
- Expression
- ufo.getQuery("http://foo.com/?toString=a")
- Reported output
- { toString: [ [Function: toString], 'a' ] }
- Where that came from
- Read mechanically from the report's fenced code, REPL form: `> ufo.getQuery("http://foo.com/?toString=a") { toString: [ [Function: toString], 'a' ] }`.
03What happened
No failure was captured.
Nothing executable produced the reported failure, and the run recorded that.
The LIVE grading as emitted. A check that did not apply is never shown as a pass.
| Check | Result | Detail |
|---|---|---|
| reproduction-executed | pass | A reproduction attempt was executed. |
| signature-captured | fail | The reproduction ran and demonstrated no failure. |
| right-failure | fail | Expected `ufo.getQuery("http://foo.com/?toString=a")` still producing { toString: [ [Function: toString], 'a' ] }. |
| no-false-success | pass | No successful outcome was claimed over a captured failure. |
| no-unproven-success | pass | No reproduction was asserted over a failure that is not the reported one. |
bench/external/scorecard.json, the run of 2026-09-20 against all 158 upstream checkouts.
The same case, graded from the transcript recorded .
The grading the benchmark gate runs on. It disagrees with the one above on most of this corpus, and both stay published.
Check it yourself
Everything here is downstream of a public commit.
Clone it, check out e383832, run the report through the CLI the way the study did.
git clone https://github.com/unjs/ufo git checkout e383832e6aa1253a0b423cbb588bc0716f274f83 npm install CREDDA_PROVIDER=heuristic \ npx tsx apps/cli/src/main.ts fix <repo-path> @<issue-file> --no-color