Skip to content

fix(security): prevent NoSQL injection from user-controlled data (SonarQube jssecurity:S5147) - #197

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/sonarqube-fix-AZhSVLrd4wErqc9Ey1Y3-1786784671
Open

fix(security): prevent NoSQL injection from user-controlled data (SonarQube jssecurity:S5147)#197
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/sonarqube-fix-AZhSVLrd4wErqc9Ey1Y3-1786784671

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 15, 2026

Copy link
Copy Markdown

Summary

Remediates SonarQube issue AZhSVLrd4wErqc9Ey1Y3 (rule jssecurity:S5147, BLOCKER) at routes/index.js:39.

loginHandler passed req.body.username / req.body.password straight into a Mongo query. Because Express body parsing yields objects for JSON bodies, a payload like {"username": "a@b.com", "password": {"$gt": ""}} injects a query operator and bypasses authentication.

+  if (typeof req.body.username !== 'string' || typeof req.body.password !== 'string') {
+    return res.status(401).send()
+  }
   if (validator.isEmail(req.body.username)) {
-    User.find({ username: req.body.username, password: req.body.password }, ...
+    User.find({ username: String(req.body.username), password: String(req.body.password) }, ...

Non-string credentials are now rejected with 401 before the query is built, so operator objects can never reach Mongo. Scoped strictly to this finding; other vulnerabilities in the file are untouched.

Note: an earlier PR (#36) exists on the exact branch name devin/sonarqube-fix-AZhSVLrd4wErqc9Ey1Y3, so this PR uses a timestamped branch.

Link to Devin session: https://app.devin.ai/sessions/dea6f4e57ffd45e38b2a35ce70907922
Requested by: @joao-cognition


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)

…be jssecurity:S5147)

Co-Authored-By: Joao Esteves <joao.esteves@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown
Author

SonarQube remediation — issue key AZhSVLrd4wErqc9Ey1Y3, rule jssecurity:S5147 (BLOCKER), project COG-GTM_nodejs-goof, routes/index.js:39.

What was changed (routes/index.js, loginHandler):

  1. Added a type guard rejecting the request with 401 unless both req.body.username and req.body.password are strings.
  2. Wrapped both values in String(...) when building the User.find({ ... }) filter.

Why: the Mongo filter was constructed directly from user-controlled JSON, so a body such as {"username": "admin@[REDACTED SECRET].com", "password": {"$gt": ""}} injected a query operator and bypassed authentication. Coercing/validating the input to primitive strings means only literal equality matches are possible.

Scope kept minimal: no other vulnerabilities in the file were touched, and the SonarQube issue status was not modified.

Comment thread routes/index.js

exports.loginHandler = function (req, res, next) {
if (typeof req.body.username !== 'string' || typeof req.body.password !== 'string') {
return res.status(401).send()
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