HIGH missing authenticationexpressdynamodb

Missing Authentication in Express with Dynamodb

Missing Authentication in Express with Dynamodb — how this specific combination creates or exposes the vulnerability

Missing authentication in an Express route that interacts with DynamoDB can expose data or enable unauthorized actions, even when the endpoint appears to be protected by other mechanisms. In this combination, the application layer fails to verify the identity of the caller before constructing and sending requests to DynamoDB. Because DynamoDB operations are executed with the permissions associated with the credentials configured for the runtime (for example, an IAM role or access keys), missing authentication may lead to over-privileged requests or data exposure if the downstream permissions are broad.

Consider an Express route designed to fetch user profile data by an identifier provided via query parameter, such as /profile. If the route does not validate an incoming token or session, an unauthenticated or low-privilege caller can supply arbitrary identifiers, including those belonging to other users. The route might construct a GetItem request using the provided identifier to query a DynamoDB table that stores sensitive user information. Without authentication checks, the request proceeds with the runtime credentials, and DynamoDB returns the data if the item exists, effectively bypassing any intended access boundaries.

Another common pattern involves using unauthenticated inputs to filter or scan DynamoDB tables. For example, an endpoint may accept a status query parameter to list records. If the application does not enforce authentication, an attacker can enumerate records by iterating through status values, leveraging the runtime permissions to scan a table that should be restricted to authenticated users. This exposes data that the application intended to protect and can lead to information disclosure, one of the findings reported by middleBrick’s Data Exposure and BOLA/IDOR checks.

In some setups, developers assume that client-side protections or network controls are sufficient and omit server-side authentication. middleBrick’s Authentication and BOLA/IDOR checks specifically test these scenarios by probing endpoints without credentials and analyzing whether DynamoDB operations depend on caller identity. When authentication is missing, middleBrick can identify paths where unauthenticated requests map to sensitive DynamoDB interactions, highlighting routes where attackers might read, modify, or infer data without authorization.

It is important to note that DynamoDB’s own access controls, such as IAM policies and resource-based permissions, operate at a different layer. They do not compensate for missing application-level authentication in Express. Overly permissive IAM policies combined with missing authentication increase risk, but the root issue remains the absence of identity verification before constructing API requests. middleBrick’s findings in such cases include guidance to enforce authentication and ensure that each request validates identity and scope before interacting with DynamoDB.

Dynamodb-Specific Remediation in Express — concrete code fixes

To remediate missing authentication, enforce identity verification in Express before performing any DynamoDB operation. Use a validated authentication mechanism, such as JWT verification or session checks, and ensure that the identity extracted from the token is used to constrain DynamoDB requests. The following example demonstrates a secure pattern using the AWS SDK for JavaScript v3 and Express.

import express from 'express';
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb';
import { unmarshall } from '@aws-sdk/util-dynamodb';
import jwt from 'jsonwebtoken';

const app = express();
const client = new DynamoDBClient({ region: 'us-east-1' });
const TABLE_NAME = process.env.PROFILE_TABLE;

function verifyToken(token) {
  const secret = process.env.JWT_SECRET;
  if (!secret) {
    throw new Error('JWT_SECRET is not configured');
  }
  return jwt.verify(token, secret);
}

app.get('/profile', (req, res) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Unauthorized: missing or invalid token' });
  }
  const token = authHeader.split(' ')[1];
  let payload;
  try {
    payload = verifyToken(token);
  } catch (err) {
    return res.status(401).json({ error: 'Unauthorized: invalid token' });
  }

  const userId = payload.sub;
  if (!userId) {
    return res.status(400).json({ error: 'Bad request: subject claim missing' });
  }

  const params = {
    TableName: TABLE_NAME,
    Key: {
      userId: { S: userId }
    }
  };

  const command = new GetItemCommand(params);
  client.send(command)
    .then(data => {
      if (!data.Item) {
        return res.status(404).json({ error: 'Not found' });
      }
      const profile = unmarshall(data.Item);
      res.json(profile);
    })
    .catch(err => {
      console.error(err);
      res.status(500).json({ error: 'Internal server error' });
    });
});

app.listen(3000, () => console.log('Server running on port 3000'));

This pattern ensures that each request includes a valid bearer token, extracts the user subject, and uses it to construct a parameterized DynamoDB query keyed by the authenticated user’s identifier. By tying the DynamoDB request to the verified subject, the application prevents unauthorized access to other users’ data even when the same endpoint is invoked with different identifiers.

For endpoints that require listing or filtering, apply the same principle: derive filter constraints from the authenticated identity rather than trusting client-provided parameters. For example, if an endpoint lists user tasks, use the authenticated user ID in the filter expression or key condition expression instead of forwarding a client-supplied value directly to DynamoDB.

In addition to code changes, operational practices matter. Ensure that the runtime credentials used by the Express application follow the principle of least privilege, granting only the necessary permissions on specific DynamoDB resources. middleBrick’s Pro plan supports continuous monitoring and CI/CD integration to detect when authentication is missing or when risk scores degrade, helping teams maintain secure configurations over time.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

Why does missing authentication in Express lead to DynamoDB data exposure even if the table has fine-grained IAM policies?
IAM policies on DynamoDB are enforced in the context of the credentials used by the application. If Express does not authenticate the caller, the request proceeds with the application’s runtime credentials, which may have broader permissions. An attacker can supply arbitrary parameters (such as user IDs), and DynamoDB will return data permitted by those credentials, bypassing intended access boundaries that would exist if the caller identity were validated first.
Can using client-side checks or network restrictions replace server-side authentication in Express before DynamoDB calls?
No. Client-side checks can be bypassed, and network restrictions do not validate identity. Without server-side authentication in Express, any caller that reaches the endpoint can influence DynamoDB requests. Authentication must be enforced in the application layer before constructing and sending requests to DynamoDB to ensure that each operation is tied to a verified identity.