fix: reject __proto__/constructor/prototype filter keys (prototype pollution) - #172
Open
BrianWillows wants to merge 1 commit into
Open
fix: reject __proto__/constructor/prototype filter keys (prototype pollution)#172BrianWillows wants to merge 1 commit into
BrianWillows wants to merge 1 commit into
Conversation
…llution)
The filter reducer assigns result[key][op] = value where key comes straight
from the query-string parameter name. For key '__proto__', result['__proto__']
resolves via the getter to Object.prototype, so the assignment writes an
attacker-controlled, enumerable property onto Object.prototype for the whole
process (CWE-1321).
aqp('__proto__>5') was enough to set Object.prototype.$gt = 5, and the
library's intended input is exactly an untrusted query string.
Reject the three prototype-walking key names in the same filter that already
applies blacklist/whitelist. They are not usable Mongo field names, so no
legitimate query is affected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
The filter reducer assigns into an object using the query-string parameter
name as the key, with no guard on prototype-walking names:
When
keyis__proto__,result['__proto__']resolves through the getter toObject.prototype, so the assignment writes an attacker-controlled, enumerableproperty onto the prototype of every object in the process (CWE-1321 prototype
pollution).
Reproduced on 6.1.0:
The library's intended input is exactly an untrusted query string
(
aqp(req.query)in an Express/Mongo API), so this is reachable directly from arequest. No configuration is needed —
blacklistdefaults to empty andwhitelistis undefined.The polluted keys are limited to Mongo operators (
$gt,$gte,$lt,$lte,$ne,$nin), so this is not an arbitrary-gadget pollution, but the value isfully attacker-controlled and the property is enumerable — every
for (k in obj)in the process then yields it, which corrupts query shapes and object iteration
generally.
Fix
Reject the three prototype-walking key names in the same filter that already
applies
blacklist/whitelist. They are not usable Mongo field names, so nolegitimate query is affected.
Verification
ava, 65 tests passed).aqp('__proto__>5')now returns{"filter":{}}and({}).$gtstaysundefined; theconstructor,prototypeand!=a,b/$ninvariants areblocked too.
aqp('status=sent&price>100&sort=-date&limit=5')still yields{"sort":{"date":-1},"limit":5,"filter":{"status":"sent","price":{"$gt":100}}}.Notes
Found and fixed with AI assistance (Claude). Happy to add a regression test to
the suite if you'd like one.