Fix NoSQL Injection in Spiral
Spiral's MongoDB bridge and ODM components are susceptible to NoSQL injection if raw request arrays are piped directly into query criteria. In PHP, JSON payloads can be manipulated to include nested associative arrays containing MongoDB operators like $ne, $gt, or $regex, allowing attackers to bypass authentication or exfiltrate data. To secure Spiral, you must enforce strict schema validation via Filters and ensure input is cast to scalar types before hitting the persistence layer.
The Vulnerable Pattern
public function login(Request $request, DatabaseInterface $db): array { // VULNERABLE: Directly passing request data into the find query. // Attacker sends: {"username": {"$ne": null}, "password": {"$ne": null}} $payload = $request->getParsedBody();$user = $db->selectCollection('users')->findOne([ 'username' => $payload['username'], 'password' => $payload['password'] ]); return $user ? ['status' => 'ok'] : ['status' => 'fail'];
}
The Secure Implementation
The vulnerability stems from the MongoDB driver's ability to interpret associative arrays as operators. When you pass $request->getParsedBody() directly, an attacker can replace a string value with an array like ['$gt' => ''], causing the query logic to change from 'equals' to 'greater than'. The fix involves two layers: 1) Using Spiral's Filter component to validate that the input matches the expected structure and type. 2) Explicitly casting values to (string) or (int) before query construction to ensure any injected arrays are flattened into harmless strings.
public function login(LoginFilter $filter, DatabaseInterface $db): array { // SECURE: Spiral Filters (DTOs) enforce type-casting and schema. // The 'username' and 'password' are mapped to scalar strings. // Even if an array is sent, the Filter component will fail or cast it.$user = $db->selectCollection('users')->findOne([ 'username' => (string)$filter->username, 'password' => (string)$filter->password ]); return $user ? ['status' => 'ok'] : ['status' => 'fail'];}
// LoginFilter Definition class LoginFilter extends Filter { protected const SCHEMA = [ ‘username’ => ‘post:username’, ‘password’ => ‘post:password’ ];
protected const VALIDATES = [ 'username' => ['notEmpty', 'string'], 'password' => ['notEmpty', 'string'] ];
}
Your Spiral API
might be exposed to NoSQL Injection
74% of Spiral apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.