[Fix] stringify: skip null/undefined filter-array entries instead of crashing in encoder by gregkh · Pull Request #551 · ljharb/qs (original) (raw)

ljharb

requested changes Apr 15, 2026

@ljharb ljharb marked this pull request as draft

April 15, 2026 23:10

@gregkh gregkh marked this pull request as ready for review

April 19, 2026 09:18

@ljharb ljharb changed the title[Fix] stringify: skip null/undefined filter-array entries instead o… [Fix] stringify: skip null/undefined filter-array entries instead of crashing in encoder

Apr 22, 2026

@ljharb

…f crashing in encoder

When filter is an array, its elements become objKeys directly and the top-level loop passes each entry as the recursive prefix argument without coercion. A null or undefined entry reached utils.encode as the str argument and str.length threw TypeError.

The crash requires two conditions to align: the filter array must contain null/undefined, and the object being stringified must have a literal 'null'/'undefined' property (otherwise obj[key] is undefined and the typeof-undefined early-return at stringify.js:137 fires before the encoder is called)

Both are reachable from an attacker controlled input in applications that stringify user-submitted JSON with user-selected fields.

Fix this up by skipping null/undefined filter entries at the top-level loop. This somewhat matches JSON.stringify replacer-array semantics, which silently ignore non-string/non-number entries. Object.keys never yields null/undefined, so the guard only affects user-supplied filter arrays. The inner recursive loop already coerces key via String() when building keyPrefix, so it never passes a raw null to the encoder.

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

[ Show hidden characters]({{ revealButtonHref }})