HIGH data exposurestrapibearer tokens

Data Exposure in Strapi with Bearer Tokens

Data Exposure in Strapi with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Strapi is a headless CMS that often exposes REST and GraphQL endpoints. When endpoints rely on Bearer token authentication implemented incompletely, data exposure can occur in at least three dimensions: authentication bypass, authorization flaws, and insecure transmission or storage.

First, authentication bypass can happen if the API accepts a Bearer token but does not enforce token validation on certain routes. For example, an endpoint like /api/articles might check for the presence of an Authorization header but skip verifying token scope or validity, allowing unauthenticated requests to receive sensitive data such as draft entries or unpublished content.

Second, authorization flaws (BOLA/IDOR) can amplify data exposure when Bearer tokens do not enforce tenant or user boundaries. A token issued to one user could be reused to access another user’s data if the backend only checks that a valid token exists, without confirming that the resource belongs to the token’s subject. This can lead to horizontal privilege escalation where one user views or modifies another user’s records.

Third, insecure transmission or storage of Bearer tokens creates exposure. If tokens are transmitted over non-TLS channels, they can be intercepted. Additionally, if Strapi logs Authorization headers or stores tokens in browser-accessible locations (such as local storage or insecure cookies), tokens may be exfiltrated via XSS or log scraping. Even when TLS is used, weak token entropy or lack of rotation increases the risk that a stolen token can be used to expose sensitive data across the API.

These three dimensions—authentication bypass, authorization flaws, and transmission/storage weaknesses—interact in Strapi deployments to create data exposure scenarios. A scanner that tests unauthenticated attack surfaces and inspects OpenAPI specs can surface these risks by identifying endpoints that accept Bearer tokens without proper validation, scope checks, or tenant isolation, and by correlating findings with insecure transport or storage practices.

Bearer Tokens-Specific Remediation in Strapi — concrete code fixes

Remediation focuses on strict token validation, scope and tenant checks, and secure handling of tokens in both transit and storage. Below are concrete code examples and configuration steps.

1. Enforce Bearer token validation on every request

Ensure Strapi middleware validates the token on each request and rejects malformed or missing tokens. In a custom middleware (e.g., src/middlewares/auth.js), validate the token before proceeding:

// src/middlewares/auth.js
module.exports = (config, { strapi }) => {
  return async (ctx, next) => {
    const auth = ctx.request.header.authorization || '';
    const token = auth.startsWith('Bearer ') ? auth.slice(7) : null;

    if (!token) {
      ctx.status = 401;
      ctx.body = { error: 'Unauthorized', message: 'Missing Bearer token' };
      return;
    }

    try {
      // Replace with your actual token verification logic
      const payload = await strapi.plugin('auth').service('jwt').verify(token);
      ctx.state.user = payload;
      await next();
    } catch (err) {
      ctx.status = 401;
      ctx.body = { error: 'Unauthorized', message: 'Invalid Bearer token' };
    }
  };
};

Register this middleware in config/middlewares.js so it runs before routes that expose sensitive content.

2. Enforce scope and tenant checks in controllers

After verifying the token, confirm that the token’s scope or tenant matches the requested resource. For example, in an articles controller, validate ownership or tenant ID:

// src/api/article/controllers/article.js
module.exports = {
  async find(ctx) {
    const user = ctx.state.user;
    if (!user || !user.scope) {
      return ctx.unauthorized('Insufficient scope');
    }

    // Assuming tenantId is part of the token and articles are scoped to tenant
    const where = { tenantId: user.scope.tenantId };
    // Optionally restrict by user-specific permissions
    if (user.scope.role !== 'admin') {
      where.published = true; // only published for non-admins
    }

    const articles = await strapi.db.query('api::article.article').findMany({ where });
    return articles;
  },
};

This prevents horizontal IDOR by ensuring users only access data within their tenant or scope, even when a valid Bearer token is presented.

3. Secure token transmission and storage

Always require HTTPS for API endpoints and set secure cookie attributes if storing tokens server-side. In Strapi’s server configuration, enforce strict transport security and avoid logging Authorization headers:

// config/server.js
module.exports = {
  settings: {
    host: '0.0.0.0',
    port: 1337,
    admin: {
      autoOpen: false,
    },
    https: {
      key: '/path/to/key.pem',
      cert: '/path/to/cert.pem',
    },
    security: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'https:'],
          'media-src': ["'self'", 'https:'],
          'script-src': ["'self'", 'cdn.jsdelivr.net', 'https:'],
          'style-src': ["'self'", 'https:'],
        },
      },
    },
  },
};

On the client side, avoid storing Bearer tokens in local storage. Use short-lived tokens and refresh token rotations to reduce the impact of token leakage.

4. Validate and sanitize inputs to reduce injection risks

Even when Bearer tokens are handled correctly, input validation remains essential to prevent SSRF or injection that could lead to data exposure. Use Strapi’s built-in validation or a library to sanitize query parameters and payloads:

// Example validation in a custom controller
const sanitizeEntity = require('strapi-utils/lib/sanitize-entity');

module.exports = {
  async find(ctx) {
    const { page = 1, pageSize = 10, q = '' } = ctx.query;
    // Validate and sanitize inputs
    const safeQ = q.replace(/[^a-zA-Z0-9 _-]/g, '').substring(0, 100);
    const where = safeQ ? { title: { $contains: safeQ } } : {};
    const [data, meta] = await strapi.db.query('api::article.article').findManyAndCount({
      where,
      pagination: { page: Number(page), pageSize: Number(pageSize) },
    });
    const entities = data.map(entity => sanitizeEntity(entity, { model: 'api::article.article' }));
    return entities;
  },
};

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

How does Strapi Bearer token misconfiguration lead to data exposure across the three dimensions?
If token validation is skipped, tokens are transmitted without TLS, or token-bound authorization (scope/tenant) is missing, an attacker can use a Bearer token to access unauthorized data (authentication bypass), escalate across tenants (authorization flaw), or intercept tokens via insecure channels or logs (transmission/storage exposure).
Can middleBrick detect these Bearer token issues in Strapi during a scan?
Yes. middleBrick tests unauthenticated attack surfaces and maps findings to frameworks like OWASP API Top 10. It can identify endpoints accepting Bearer tokens without proper validation or tenant isolation, and surface related data exposure risks alongside remediation guidance.