HIGH nosql injectionfiberhmac signatures

Nosql Injection in Fiber with Hmac Signatures

Nosql Injection in Fiber with Hmac Signatures — how this specific combination creates or exposes the vulnerability

NoSQL injection is a class of injection that targets database queries constructed from untrusted input. In the Go web framework Fiber, routes often parse JSON or form values and forward them directly to a database driver. When HMAC signatures are used for request authentication but the signature is not tied to the integrity of the query parameters, an attacker can manipulate those parameters and inject malicious operators.

Consider a typical authentication flow where a request must include an X-API-Signature header computed over selected parameters. If the server verifies the HMAC but then builds a database query using the same parameters without further validation, the signature confirms the parameter was agreed upon by the client and server, but it does not prevent malicious content within those parameters. For example, an authenticated request might include {"filter": {"$where": "true"}}. The HMAC ensures the client supplied that filter, yet the database may still evaluate the operator, leading to NoSQL injection.

In a real-world pattern, a developer might compute the HMAC over a subset of the JSON body or query string to prevent tampering. However, if the server deserializes the JSON into a map and directly passes values to a MongoDB Find call, operators like $ne, $regex, or $where can alter query logic. The combination of Hmac Signatures for integrity and untrusted data used in query construction creates a false sense of security: the signature is valid, but the data it covers is interpreted as code by the database.

Another scenario involves ID-based lookups where an authenticated request provides user_id in both the HMAC payload and the URL path. If the server trusts the HMAC and uses the user_id to fetch documents without type or range checks, an attacker who can influence the signature (e.g., via a shared secret compromise or replay) can pivot to other users’ data or inject conditions that bypass intended authorization checks. This intersects with BOLA/IDOR when the signature does not bind the parameter to a specific subject or session.

Middleware that verifies Hmac Signatures in Fiber should not automatically promote incoming parameter values into database directives. Instead, treat authenticated input as untrusted and apply strict allow-lists, type checks, and schema validation before using values in query construction. NoSQL injection in this context is not about breaking the signature algorithm; it is about the misuse of authenticated data within the database layer.

Hmac Signatures-Specific Remediation in Fiber — concrete code fixes

To mitigate NoSQL injection while using Hmac Signatures in Fiber, decouple authentication from data usage. Verify the signature, then validate and sanitize each parameter before it reaches the database. Below are two concrete patterns: one using explicit binding and another using a strict schema-driven approach.

Example 1: Explicit parameter binding with HMAC verification

const crypto = require('crypto');
const { app } = require('github.com/gofiber/fiber/v2');

const SHARED_SECRET = process.env.SHARED_SECRET; // keep this secret

function verifySignature(body, signature) {
  const expected = crypto.createHmac('sha256', SHARED_SECRET)
                         .update(JSON.stringify(body))
                         .digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

app.post('/users/:user_id', (req, res) => {
  const signature = req.get('X-API-Signature');
  if (!signature || !verifySignature(req.body, signature)) {
    return res.status(401).send({ error: 'invalid signature' });
  }

  // Explicitly extract and validate each field
  const userId = req.params.user_id;
  const bodyUserId = req.body.user_id;
  if (bodyUserId !== undefined && bodyUserId !== userId) {
    return res.status(400).send({ error: 'user_id mismatch' });
  }

  // Use only the path parameter for lookup, ignore untrusted body for query construction
  const safeUserId = Number(userId);
  if (!Number.isInteger(safeUserId) || safeUserId <= 0) {
    return res.status(400).send({ error: 'invalid user id' });
  }

  // Build query with bound values, not raw user input
  const query = {
    filter: {
      _id: safeUserId,
      // other safe, explicitly mapped fields
    },
    projection: { name: 1, email: 1 }
  };

  // db.collection('users').find(query) — query uses safeUserId, not req.body.filter
  return res.send({ ok: true });
});

Example 2: Schema validation before database interaction

const { app } = require('github.com/gofiber/fiber/v2');
const Ajv = require('ajv');
const ajv = new Ajv();

const requestSchema = {
  type: 'object',
  required: ['action'],
  properties: {
    action: { enum: ['get_profile', 'update_email'] },
    email: { type: 'string', format: 'email' },
    // No operator-like fields allowed
  },
  additionalProperties: false
};

const verifySignature = (body, signature) => {
  // same HMAC logic as above
};

app.post('/command', (req, res) => {
  const signature = req.get('X-API-Signature');
  if (!signature || !verifySignature(req.body, signature)) {
    return res.status(401).send({ error: 'invalid signature' });
  }

  const validate = ajv.compile(requestSchema);
  const valid = validate(req.body);
  if (!valid) {
    return res.status(400).send({ errors: validate.errors });
  }

  // Map validated business actions to safe queries
  if (req.body.action === 'get_profile') {
    const query = {
      filter: { user_id: req.user.id },
      projection: { name: 1, email: 1 }
    };
    // db.collection('users').find(query)
    return res.send({ action: 'profile' });
  }

  return res.status(400).send({ error: 'unknown action' });
});

In both examples, Hmac Signatures confirm the request’s origin, but the server never uses raw, untrusted input to construct database queries. Path parameters are bound explicitly, and request bodies are validated against a strict schema that disallows operator-like keys such as $where or $regex. This approach aligns with remediations for weaknesses identified in the OWASP API Top 10 and helps prevent NoSQL injection while maintaining the integrity checks provided by Hmac Signatures.

Frequently Asked Questions

Does using Hmac Signatures prevent NoSQL injection in Fiber?
No. Hmac Signatures provide integrity and authentication but do not sanitize or validate data. If authenticated parameters are used directly in database queries, NoSQL injection can still occur. Always validate and bind values rather than passing raw input to the database.
How can I safely combine Hmac Signatures with user input in Fiber APIs?
Verify the HMAC first, then extract only the fields you need, apply strict type checks and allow-lists, and construct queries using bound values or an ORM that avoids string-based operators. Never concatenate authenticated input into query strings or aggregation pipelines.