rastray 0.15.0

Blazing-fast static analysis CLI for security, dependency, and performance audits.
# RSTR-NOSQLI-003 — PyMongo filter built from `request.*`

## Summary

A PyMongo query is built by passing a request-derived dict (or `request.json`,
`request.form`, `request.values`) directly as the filter argument. An
attacker who submits `{"$gt": ""}` instead of a string causes the filter
to match every document — bypassing intended access controls.

This is the Python counterpart of [`RSTR-NOSQLI-001`](./RSTR-NOSQLI-001.md).

## Severity

`High`.

## Languages

Python (PyMongo / Motor).

## What rastray flags

```python
db.users.find_one(request.json)                  # ← flagged
db.posts.update_one(request.form, {'$set': ...}) # ← flagged
```

## What rastray deliberately does *not* flag

- Filters constructed from individual fields:
  `db.users.find_one({'_id': ObjectId(request.json['id'])})`.
- Filters built after `marshmallow` / `pydantic` schema validation.

## How to fix it

Validate and coerce inputs before building the filter. With pydantic:

```python
from pydantic import BaseModel
from bson import ObjectId

class UserQuery(BaseModel):
    id: str
    email: str | None = None

@app.post('/users')
def find_user(q: UserQuery = Depends(...)):
    return db.users.find_one({
        '_id':   ObjectId(q.id),
        'email': q.email,
    })
```

Plain dict construction also works as long as each field comes through
a per-field coercion (string, int, etc.) — the rule fires precisely
because passing the entire request object lets operator keys through.

## References

- [PyMongo: query operators]https://www.mongodb.com/docs/manual/reference/operator/query/
- [OWASP NoSQL Injection]https://owasp.org/www-community/Injection_Flaws
- [CWE-943: Improper Neutralization of Special Elements in Data Query Logic]https://cwe.mitre.org/data/definitions/943.html