HIGH nosql injectionhmac signatures

Nosql Injection with Hmac Signatures

How Nosql Injection Manifests in Hmac Signatures

Nosql Injection in Hmac Signatures contexts typically occurs when cryptographic signatures are used to authenticate database queries without proper input sanitization. Attackers can manipulate signature parameters to inject NoSQL operators like $where, $ne, or $regex into query conditions.

Consider a Node.js API that verifies HMAC signatures before executing database operations:

const crypto = require('crypto');
const db = require('./db');

async function verifyAndQuery(req) {
  const { userId, signature } = req.body;
  
  // Verify HMAC signature
  const computedSig = crypto.createHmac('sha256', process.env.SECRET_KEY)
    .update(userId)
    .digest('hex');
  
  if (computedSig !== signature) {
    return { error: 'Invalid signature' };
  }
  
  // Execute query based on signed userId
  return await db.collection('users').findOne({ _id: userId });
}

The vulnerability appears when userId contains NoSQL operators. An attacker can craft a payload like:

{
  "userId": "{ \"$where\": \"this.isAdmin === true\" }",
  "signature": "valid-hmac-here"
}

Since the HMAC verification passes (the signature is valid for the string value), the NoSQL query executes with the injected operator, potentially returning admin users or bypassing authorization.

Another attack vector involves exploiting type coercion in NoSQL databases. MongoDB, for example, treats strings and ObjectId differently:

// Malicious payload
{
  "userId": "{ \"$ne\": \"valid-user-id\" }",
  "signature": "hmac-of-string"
}

This returns all users except the specified one, leaking data through information disclosure.

Hmac Signatures-Specific Detection

Detecting NoSQL Injection in HMAC-signed requests requires examining both the cryptographic validation logic and the database query construction. middleBrick's scanner specifically tests for this by:

  1. Crafting HMAC signatures for payloads containing NoSQL operators
  2. Observing database responses to determine if operators are being executed
  3. Checking for timing differences that might indicate conditional query execution

The scanner tests 12 common NoSQL injection patterns in HMAC contexts:

middlebrick scan https://api.example.com/verify-signature \
  --payload-type nosql-hmac \
  --test-patterns $where,$ne,$gt,$regex,$size,$exists,$all,$elemMatch,$not,$nor,$and,$or

Key detection indicators include:

IndicatorDescriptionRisk Level
Operator executionDatabase returns results matching injected NoSQL operatorsCritical
Timing analysisResponse times vary based on conditional logic in NoSQL queriesHigh
Type coercionDifferent results when string vs ObjectId values are usedMedium
Schema leakageAPI reveals database structure through error messagesMedium

middleBrick also analyzes OpenAPI specifications to identify endpoints using HMAC signatures and flags those that accept complex objects rather than simple primitives, which are more susceptible to NoSQL injection.

Hmac Signatures-Specific Remediation

Securing HMAC-signed endpoints against NoSQL injection requires defense in depth. The primary strategies are strict input validation, type enforcement, and query parameterization.

First, enforce strict type validation before signature verification:

async function verifyAndQuery(req) {
  const { userId } = req.body;
  
  // Validate userId is a simple string without special characters
  if (typeof userId !== 'string' || /[^a-zA-Z0-9-]/.test(userId)) {
    return { error: 'Invalid userId format' };
  }
  
  // Verify HMAC signature
  const computedSig = crypto.createHmac('sha256', process.env.SECRET_KEY)
    .update(userId)
    .digest('hex');
  
  if (computedSig !== req.body.signature) {
    return { error: 'Invalid signature' };
  }
  
  // Use parameterized queries with strict typing
  const query = { _id: new ObjectId(userId) };
  return await db.collection('users').findOne(query);
}

Key improvements:

  • Input validation rejects objects and special characters before HMAC verification
  • Type coercion is prevented by explicitly converting to ObjectId
  • Query parameters are constructed separately from user input
  • For APIs that must accept complex objects, use a two-step validation approach:

    function validateAndNormalizePayload(payload) {
      // Create a whitelist of allowed fields
      const allowedFields = ['userId', 'timestamp', 'action'];
      
      // Ensure payload is a flat object with only allowed fields
      const normalized = {};
      for (const field of allowedFields) {
        if (field in payload) {
          const value = payload[field];
          // Reject objects, arrays, and special characters
          if (typeof value === 'object' || /[^a-zA-Z0-9-_.]/.test(String(value))) {
            throw new Error('Invalid field value');
          }
          normalized[field] = String(value);
        }
      }
      return normalized;
    }

    Additional protections include:

    • Using database query builders that automatically escape NoSQL operators
    • Implementing rate limiting to slow brute-force attempts
    • Adding audit logging for all HMAC-verified operations
    • Using constant-time comparison for signature verification to prevent timing attacks

Frequently Asked Questions

Why doesn't HMAC signature verification prevent NoSQL injection?
HMAC signatures verify message integrity and authenticity, but they don't validate the semantic meaning or structure of the data. An attacker can create a valid HMAC signature for a payload containing NoSQL operators, and the signature verification will pass because the data hasn't been modified in transit. The vulnerability occurs in how the signed data is processed after verification.
Can NoSQL injection in HMAC contexts lead to authentication bypass?
Yes. If HMAC signatures are used to authenticate users and then the user identifier is used directly in NoSQL queries without validation, attackers can inject operators like $where or $ne to manipulate query results. This can return unauthorized data or even bypass authentication checks by exploiting conditional logic in the database queries.