HIGH nosql injectionexpressbasic auth

Nosql Injection in Express with Basic Auth

Nosql Injection in Express with Basic Auth

Combining Express.js, Basic Authentication, and a NoSQL database such as MongoDB can introduce injection and bypass risks when requests, headers, and credentials are not rigorously validated. In this setup, the Authorization header carries a base64-encoded username:password pair decoded server-side. If the application uses that decoded username to build a NoSQL query without proper sanitization, injection becomes possible. For example, an attacker may supply a username like {'$ne': null} which, when interpolated into a query object, alters the intended logic and may bypass authentication.

Consider an implementation that decodes Basic Auth and directly uses the username in a MongoDB query:

const authHeader = req.headers.authorization; // 'Basic dXNlcjpwYXNz'
const base64 = authHeader && authHeader.split(' ')[1];
const decoded = Buffer.from(base64, 'base64').toString('utf-8'); // 'user:pass'
const [username, password] = decoded.split(':');

// Unsafe: username used directly in query
User.find({ username: username, password: password }, (err, user) => {
  res.send(user ? 'OK' : 'Unauthorized');
});

If username is {'$ne': null} and the database driver parses this as an operator, the query may return a document where the username does not match, potentially allowing authentication as an arbitrary user. Injection here is not limited to strings; nested objects and operators such as $in, $regex, $where, or $or can be supplied via crafted credentials or request parameters that flow into the query construction.

Another risk occurs when endpoints accept JSON bodies or query parameters that are merged into NoSQL queries. An attacker might send a payload like {username: {'$regex': '^admin'}} to enumerate users or escalate privileges. Because Basic Auth is static per request, applications may inadvertently trust decoded credentials more than they should, especially when combined with permissive query building. Injection in this context can lead to authentication bypass, information disclosure, or unauthorized data access.

middleBrick detects such patterns by analyzing the OpenAPI/Swagger spec and correlating runtime behavior. It identifies places where user-controlled data—including decoded Basic Auth components—reach NoSQL query constructors and flags inputs that could modify query logic. The scanner tests for injection via canonical NoSQL injection techniques, ensuring that operators are not unintentionally trusted.

Basic Auth-Specific Remediation in Express

Secure remediation focuses on strict input validation, avoiding direct interpolation of user-controlled values into query objects, and using parameterized APIs or an ORM/ODM that does not treat strings as executable query syntax. Never rely on encoding or obscurity; treat the decoded username and password as untrusted input.

First, validate and normalize the username before using it in a query. For string usernames, allow only a known safe pattern (e.g., alphanumeric with limited special characters) and reject anything that resembles operators or control flow constructs:

const allowedUsername = /^[a-zA-Z0-9._-]{3,32}$/;

function validateUsername(value) {
  if (!value || !allowedUsername.test(value)) {
    throw new Error('Invalid username');
  }
  return value;
}

Second, avoid building query objects by concatenating or destructuring decoded credentials. Instead, explicitly map fields and use placeholders or ORM/ODM methods that separate data from query structure. With Mongoose, prefer schema-based operations:

const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({ username: String, passwordHash: String });
const User = mongoose.model('User', userSchema);

async function authenticate(req, res) {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    return res.status(401).send('Unauthorized');
  }
  const base64 = authHeader.split(' ')[1];
  const decoded = Buffer.from(base64, 'base64').toString('utf-8');
  const [username, password] = decoded.split(':');

  try {
    const safeUser = validateUsername(username);
    // Use schema methods; do not merge raw user input into query objects
    const user = await User.findOne({ username: safeUser }).exec();
    if (!user || user.passwordHash !== hashPassword(password)) {
      return res.status(401).send('Unauthorized');
    }
    res.send('OK');
  } catch (err) {
    res.status(400).send('Bad Request');
  }
}

Third, if you must construct query objects from user input, use defensive copying and explicitly whitelist allowed keys. For MongoDB, avoid passing raw user objects directly to find or update. Instead, pick known fields and sanitize values. Reject any keys that start with $, as these are operators:

function sanitizeQuery(input) {
  const safe = {};
  for (const key of Object.keys(input)) {
    if (key.startsWith('$')) continue; // reject operators
    safe[key] = input[key];
  }
  return safe;
}

Finally, enforce transport security and consider moving away from Basic Auth for modern applications. Use HTTPS to protect credentials in transit, and evaluate more robust mechanisms such as token-based authentication with short-lived credentials and proper scopes. middleBrick’s scans can verify that such mitigations are reflected in the API surface by correlating spec definitions with runtime tests, including checks for unauthenticated LLM endpoints and other security controls.

Frequently Asked Questions

Can an attacker bypass authentication using special characters in the Basic Auth username?
Yes. If the application uses the decoded username directly in a NoSQL query without validation, operators like {'$ne': null} or {'$regex': '^admin'} can alter query logic and enable bypass. Always validate and sanitize credentials before building queries.
Does middleBrick fix the identified injection issues?
middleBrick detects and reports findings with remediation guidance but does not fix, patch, block, or remediate. It provides a security risk score and prioritized findings to help teams address issues such as NoSQL injection and Basic Auth misuse.