Skip to content

[Security Fix] SAST: NoSQL/server-side JS injection via $where with unsanitized threshold query ...#413

Open
okaypatrick wants to merge 1 commit into
OWASP:masterfrom
okaypatrick:fix/security-80952f91
Open

[Security Fix] SAST: NoSQL/server-side JS injection via $where with unsanitized threshold query ...#413
okaypatrick wants to merge 1 commit into
OWASP:masterfrom
okaypatrick:fix/security-80952f91

Conversation

@okaypatrick
Copy link
Copy Markdown

Security Fix

Type: SAST
Generated by: AI-Powered Fix Generator
Finding: NoSQL/server-side JS injection via $where with unsanitized threshold query parameter.
Rule: claude-nosql-injection-allocations (oogway-scanner)
File: app/data/allocations-dao.js (line 70)
Severity: HIGH

Explanation

The previous code built a MongoDB $where clause by interpolating the raw threshold query parameter directly into a JavaScript string evaluated server-side by MongoDB. An attacker could inject arbitrary JS (e.g. 0';while(true){}' for a DoS, or 1'; return 1 == '1 to bypass filtering and exfiltrate all allocations), since the value was wrapped only in single quotes with no validation or escaping.

The fix removes $where entirely and replaces it with a standard, safely-typed MongoDB query: threshold is parsed with parseInt and validated to be an integer in the expected 0–99 range, then used with the $gt operator alongside the already-parsed userId. This preserves the original filtering semantics (same userId, stocks greater than threshold) while making server-side JS injection impossible. Invalid thresholds still throw, matching the previously-intended behavior.

Changes

  • app/data/allocations-dao.js: Replace the unsafe $where clause built via string interpolation of the user-supplied threshold with a validated integer and a standard MongoDB query operator ($gt). This eliminates server-side JavaScript injection while preserving the filtering behavior.

Test Suggestions

  • Request /allocations/:userId?threshold=50 and verify only allocations with stocks > 50 are returned.
  • Request /allocations/:userId?threshold=0';while(true){}' and verify the request is rejected (validation error) rather than hanging the server.
  • Request /allocations/:userId?threshold=1';%20return%201%20==%20'1 and verify it does not bypass filtering.
  • Request /allocations/:userId?threshold=-1 and threshold=100 and verify both are rejected as invalid.
  • Request /allocations/:userId with no threshold and verify all allocations for that user are returned (unchanged behavior).

… `threshold` query parameter.

The previous code built a MongoDB `$where` clause by interpolating the raw `threshold` query parameter directly into a JavaScript string evaluated server-side by MongoDB. An attacker could inject arbitrary JS (e.g. `0';while(true){}'` for a DoS, or `1'; return 1 == '1` to bypass filtering and exfiltrate all allocations), since the value was wrapped only in single quotes with no validation or escaping.

The fix removes `$where` entirely and replaces it with a standard, safely-typed MongoDB query:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant