GuardAPI Logo
GuardAPI

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']
];

}

System Alert • ID: 2411
Target: Spiral API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.