Detecting NoSQL injection

Description

The product category filter for this lab is powered by a MongoDB NoSQL database. It is vulnerable to NoSQL injection.

To solve the lab, perform a NoSQL injection attack that causes the application to display unreleased products.

Approach

pon accessing the lab, I immediately activated the FoxyProxy Firefox extension to proxy the requests through Burp Suite. As I began navigating the site, I scrutinized various requests to identify potential vulnerabilities, and one particular request caught my attention:

GET /filter?category=Corporate+gifts HTTP/2
Host: 0a0e006004117b6580c0097a00a50052.web-security-academy.net
Cookie: session=r1XIdBsP1RYdIrF1VhhohfOAzdBLYxIo
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
...

This request, which sends a GET request to the server with a parameter named "category" to fetch items corresponding to that category, seemed promising for injection. To test for vulnerabilities, I injected a simple special character to see if I could trigger any errors:

GET /filter?category='

My suspicion was confirmed when I received the following error message, indicating that I had successfully disrupted the query being sent and uncovered a potential injection point:

Command failed with error 139 (JSInterpreterFailure): 'SyntaxError: unterminated string literal :
functionExpressionParser@src/mongo/scripting/mozjs/mongohelpers.js:46:25
' on server 127.0.0.1:27017. The full response is {"ok": 0.0, "errmsg": "SyntaxError: unterminated string literal :\nfunctionExpressionParser@src/mongo/scripting/mozjs/mongohelpers.js:46:25\n", "code": 139, "codeName": "JSInterpreterFailure"}

Next, I aimed to verify the conditional behavior by inputting true and false statements. Injecting a false statement (Corporate gifts' && 0 && 'x) yielded no apparent changes. However, injecting a true statement (Corporate gifts' && 1 && 'x) resulted in the display of items corresponding to the "Corporate gifts" category, indicating that this style of syntax indeed influences a server-side query.

Finally, I attempted to override the existing condition and display unreleased products by injecting '||1||':

GET /filter?category=Corporate+gifts%27%7c%7c%31%7c%7c%27

As a result, I successfully viewed all products, confirming the success of the injection and solving the lab.