HIGH nosql injectionexpressbearer tokens

Nosql Injection in Express with Bearer Tokens

Nosql Injection in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability

NoSQL injection is a class of injection that targets databases such as MongoDB, CouchDB, and Cassandra. In Express applications, this often occurs when user-controlled input is directly embedded into NoSQL queries without proper validation or serialization. When combined with Bearer token authentication, the risk pattern changes: authentication may appear to be working (tokens are accepted), but the API surface exposed by token-based endpoints can still be vulnerable if query construction is unsafe.

Consider an endpoint that retrieves a user profile using a token-bound identifier. If the server decodes the Bearer token to obtain a user ID and then builds a NoSQL query by concatenating that ID, an attacker who can influence the token or the downstream query may force injection. For example, a token payload containing a malicious string like "$ne": "" in a JSON field could be parsed and later used in a MongoDB query, altering the intended filter. In a typical Express route using a library such as mongodb or mongoose, unsanitized input from request parameters, headers, or token claims can lead to unintended data access or modification.

Another scenario involves admin routes that rely on a Bearer token for authorization but then construct queries using raw user input. For instance, a search route that appends a filter parameter directly into a MongoDB query object can allow an attacker to bypass intended filters or extract sensitive documents. Real-world attack patterns mirror issues tracked in vulnerability databases, where improper input validation leads to data exfiltration or unauthorized access. Because Bearer tokens are often treated as opaque credentials, developers may overlook the need to sanitize data derived from token claims or from requests authenticated by those tokens.

In a black-box scan, middleBrick tests unauthenticated and authenticated surfaces, including endpoints protected by Bearer tokens, to detect places where NoSQL injection is possible. The tool checks whether query construction reflects attacker-controlled data, including values originating from token payloads, and flags findings that align with the OWASP API Top 10 and related compliance frameworks. Detection does not imply that tokens themselves are weak; it highlights that the application fails to neutralize malicious input before it reaches the database layer.

Bearer Tokens-Specific Remediation in Express — concrete code fixes

Securing Express APIs that use Bearer tokens requires disciplined handling of token data and strict separation between authentication and query building. Below are concrete code examples demonstrating safe practices.

1. Validate and sanitize data derived from token claims

Do not trust claims inside a decoded token. Treat them as untrusted input and validate/sanitize before using them in NoSQL queries.

const jwt = require('jsonwebtoken');
const { MongoClient } = require('mongodb');

function verifyToken(token) {
  const publicKey = process.env.JWT_PUBLIC_KEY;
  // Validate signature and standard claims
  const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
  // Explicitly whitelist expected claim names and types
  if (typeof decoded.sub !== 'string' || !decoded.sub) {
    throw new Error('Invalid subject claim');
  }
  return decoded;
}

app.get('/profile', (req, res) => {
  const auth = req.headers.authorization || '';
  const [, token] = auth.split(' ');
  if (!token) {
    return res.status(401).json({ error: 'missing_token' });
  }
  const payload = verifyToken(token);
  // Safe: using parameterized or ORM methods instead of raw concatenation
  const user = usersCollection.findOne({ _id: payload.sub });
  if (!user) {
    return res.status(404).json({ error: 'not_found' });
  }
  res.json(user);
});

2. Use database driver methods that avoid concatenation

With mongoose or the native MongoDB driver, prefer methods that do not implicitly convert objects into query strings. Avoid building query objects by string interpolation.

// Unsafe: concatenating user input into the query object
// const query = { username: req.query.username };
// const user = await User.find(query);

// Safe: explicit schema-based validation and typed queries
const user = await User.findOne({ username: req.query.username }).exec();

3. Enforce least privilege and scope tokens narrowly

Issue tokens with minimal scopes and avoid embedding database identifiers directly when possible. Use server-side mapping instead.

// Example: map token subject to internal user ID server-side
const tokenMapping = {
  'user-a-uuid': 'internal-mongo-id-123'
};
app.get('/data', (req, res) => {
  const auth = req.headers.authorization || '';
  const [, token] = auth.split(' ');
  const payload = verifyToken(token);
  const internalId = tokenMapping[payload.sub];
  if (!internalId) {
    return res.status(403).json({ error: 'forbidden' });
  }
  const record = await DataCollection.findOne({ _id: internalId });
  res.json(record);
});

4. Apply input validation on all user-influenced parameters

Even when authenticated by Bearer tokens, query parameters, headers, and body fields must be validated against a strict schema.

const Joi = require('joi');
const searchSchema = Joi.object({
  filter: Joi.string().pattern(/^[a-zA-Z0-9_\-\s]*$/).max(100).required()
});
app.get('/search', (req, res) => {
  const { error, value } = searchSchema.validate(req.query);
  if (error) {
    return res.status(400).json({ error: 'invalid_parameters' });
  }
  const results = await ItemsCollection.find({ tags: value }).toArray();
  res.json(results);
});

5. Use parameterized updates and avoid $where, $eval

Never use operators that evaluate code strings. Prefer explicit update operators and typed updates.

// Unsafe
// await User.updateOne({ _id: userId }, '$set: ' + userInput);

// Safe
await User.updateOne({ _id: userId }, { $set: { email: userInput.email } });

Frequently Asked Questions

Does using Bearer tokens guarantee protection against NoSQL injection?
No. Bearer tokens handle authentication, but they do not prevent injection if the application builds NoSQL queries using unsanitized input, including values from token claims or request parameters.
Can middleBrick detect NoSQL injection in endpoints protected by Bearer tokens?
Yes. middleBrick tests authenticated surfaces by accepting and using Bearer tokens where provided, then checking whether query construction reflects attacker-controlled data from token claims, parameters, or headers.