HIGH insecure direct object referenceexpresshmac signatures

Insecure Direct Object Reference in Express with Hmac Signatures

Insecure Direct Object Reference in Express with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Insecure Direct Object Reference (BOLA/IDOR) occurs when an API exposes internal object references (e.g., database IDs, filenames) without verifying that the requesting user is authorized to access that specific resource. In Express, this commonly manifests when an endpoint like /users/:id/profile uses a user-controlled identifier directly to fetch data, relying only on authentication (e.g., a session or JWT) without an authorization check tied to the resource ownership.

When Hmac Signatures are used for request authentication, developers sometimes assume the integrity of the signature is sufficient to prevent tampering. An Hmac Signature typically ensures that the request parameters have not been altered in transit, but it does not inherently enforce authorization. If the signature is computed over parameters that include an object identifier (such as a resource ID), and the server uses that identifier directly to load a resource, an attacker who is already authenticated as a different user can manipulate the identifier within the signed payload—provided the signature validation logic does not explicitly bind the identifier to the authenticated subject.

For example, an Express route might validate an Hmac signature and then do this:

// Vulnerable: ID from signed parameters used directly
app.get('/api/resource/:resourceId', verifyHmac, (req, res) => {
  const resourceId = req.params.resourceId;
  const resource = db.resources.findById(resourceId); // No ownership check
  if (!resource) return res.status(404).send('Not found');
  res.json(resource);
});

If the verifyHmac middleware only checks the signature validity and does not ensure that the resourceId belongs to the authenticated user (or the tenant/role context), an attacker can change the resourceId in a valid, signed request to enumerate or access other users’ resources. This is a classic BOLA/IDOR: the reference is direct and lacks proper authorization, even though the request is cryptographically signed.

In an API security scan, this pattern may be flagged under the BOLA/IDOR check and also under the Authentication/Property Authorization checks, because the signature does not prevent horizontal privilege escalation across same-level users. Data exposure can occur when sensitive records are returned without confirming the subject’s access rights. The scanner will note that the endpoint trusts an object reference without correlating it to the authenticated identity or tenant, which maps to OWASP API Top 10:2023 – Broken Object Level Authorization.

Reminder: middleBrick detects these patterns and maps findings to frameworks like OWASP API Top 10, SOC2, and GDPR, but it does not fix the code. It provides prioritized findings with remediation guidance.

Hmac Signatures-Specific Remediation in Express — concrete code fixes

To mitigate BOLA/IDOR when using Hmac Signatures in Express, you must ensure that every access to a resource validates that the authenticated subject is authorized for that specific object. The signature should cover enough context to bind the request to the subject, or the server must perform an explicit authorization check after signature validation.

Approach 1: Include the subject in the signed payload

Require the client to include the user identifier (or a derived claim) in the signed parameters. The server then verifies the signature and ensures the identifier matches the authenticated subject’s ID. This prevents the attacker from changing the ID in a valid signature because the signature would no longer match if they alter it.

// Server-side: include userId in signed parameters and verify ownership
const crypto = require('crypto');

function verifyHmac(req, res, next) {
  const signature = req.get('X-Signature');
  const userId = req.get('X-User-Id');
  const computed = crypto.createHmac('sha256', process.env.HMAC_SECRET)
    .update(req.method + '|' + req.path + '|' + userId)
      .digest('hex');
  if (!signature || signature !== computed) {
    return res.status(401).send('Invalid signature');
  }
  req.userId = userId;
  next();
}

app.get('/api/resource/:resourceId', verifyHmac, (req, res) => {
  const resourceId = req.params.resourceId;
  const userId = req.userId;
  const resource = db.resources.find((r) => r.id === resourceId && r.userId === userId);
  if (!resource) return res.status(403).send('Forbidden or not found');
  res.json(resource);
});

Approach 2: Map identifiers to subjects server-side after signature validation

If including the subject in the signature is impractical, perform a database lookup after verifying the signature and enforce that the resource belongs to the authenticated subject. This is safer than trusting client-supplied IDs, even when signed.

// After signature verification, enforce ownership
app.get('/api/resource/:resourceId', verifyHmac, async (req, res) => {
  const resourceId = req.params.resourceId;
  const userId = req.auth.userId; // from session or token
  const resource = await db.resources.findOne({ where: { id: resourceId, userId } });
  if (!resource) return res.status(403).send('Forbidden or not found');
  res.json(resource);
});

Approach 3: Use a reference mapping instead of raw IDs

Instead of exposing database IDs, use a mapping (e.g., UUIDs or scoped references) that does not reveal direct object references. The server translates the reference to an internal ID only after confirming ownership. This reduces the attack surface for enumeration.

// Using scoped references to avoid direct object references
app.get('/api/resource/:ref', verifyHmac, (req, res) => {
  const ref = req.params.ref;
  const userId = req.userId;
  // ref encodes or maps to a resource; lookup includes userId check
  const resource = db.resources.findByRefAndUser(ref, userId);
  if (!resource) return res.status(403).send('Forbidden');
  res.json(resource);
});

In all cases, ensure the Hmac signature covers the method, path, and any parameters that influence authorization. Avoid trusting only the signature to prevent tampering; couple it with explicit access control. These patterns align with remediations recommended in scans reported by middleBrick, which provides findings and guidance without fixing code directly.

For teams using the CLI, you can run middlebrick scan <url> to detect such issues; the GitHub Action can also enforce score thresholds in CI/CD, and the MCP Server allows scanning APIs directly from AI coding assistants.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

Does a valid Hmac Signature guarantee that a request is authorized to access a specific resource?
No. A valid Hmac Signature only ensures the request parameters have not been altered. It does not verify that the authenticated subject is allowed to access the referenced resource. Authorization checks must be performed separately, for example by confirming that the resource’s owner matches the authenticated user.
How can I test for BOLA/IDOR when Hmac Signatures are used in Express endpoints?
After confirming the signature is valid, attempt to access a resource with a different valid identifier that belongs to another user and verify that the server denies access. Automated scans can flag endpoints where object references are used directly without ownership checks, and the CLI (middlebrick scan) can help identify these patterns.