Skip to content
Field Detail
Platform PortSwigger Web Security Academy
Type NoSQL Injection
Difficulty Apprentice
Objective Inject an always-true condition into the MongoDB category filter to reveal unreleased products

Detecting NoSQL Injection

Testing the category filter with a single quote:

/filter?category=Lifestyle'
Screenshot
Internal Server Error
Command failed with error 139 (JSInterpreterFailure): 'SyntaxError: unterminated string literal :
functionExpressionParser@src/mongo/scripting/mozjs/mongohelpers.js:46:25'

The error is from MongoDB's mozjs JavaScript interpreter — the quote broke a string literal inside a $where-style expression. The underlying query looks like this.category == 'Lifestyle''. The error reveals both the injection point and the query engine: input reaches the query layer unsanitized and is evaluated as JavaScript. A standard field equality check ({category: input}) without $where would treat the injected characters as literal string data — the JavaScript evaluation layer is what converts syntax injection into logic manipulation.

The query structure is this.category == '<user_input>'. Injecting || true || closes the string and appends a condition that always evaluates to true:

/filter?category=Lifestyle' || true || '

Produces:

this.category == 'Lifestyle' || true || ''

The || true short-circuits the entire expression — every document passes the filter regardless of category or release status:

Screenshot

All products returned, including unreleased ones.

Lab solved :P

Resources