Broken Authentication in Strapi with Bearer Tokens
Broken Authentication in Strapi with Bearer Tokens
Broken authentication in Strapi when using Bearer Tokens occurs when token issuance, validation, or storage is implemented in a way that allows unauthorized access. Strapi is a flexible headless CMS that supports JWT-based Bearer Token authentication out of the box. However, insecure configurations or usage patterns can weaken the protection these tokens provide.
One common misconfiguration is using the default JWT secret without rotating it or using a weak secret. The secret is used to sign tokens; if it is predictable or shared across environments, an attacker can forge valid Bearer Tokens. Additionally, failing to set short expiration times (exp claim) means a stolen token remains valid for an extended period, increasing the window for abuse. In Strapi, the token payload typically includes user identity (id and email), and overly broad scopes or missing role checks can allow privilege escalation.
Another vulnerability pattern arises when Strapi APIs are exposed without proper rate limiting or account lockout mechanisms. Attackers can perform credential stuffing or brute-force attacks on the local strapi_admin or application user endpoints to obtain valid credentials and, consequently, valid Bearer Tokens. If the admin interface does not enforce multi-factor authentication (MFA), the risk is further amplified.
Insecure transmission is also a concern. If Bearer Tokens are transmitted over unencrypted channels or stored insecurely on the client (e.g., in localStorage without adequate protections), they can be intercepted or extracted via cross-site scripting (XSS). Strapi’s unauthenticated endpoints, which may expose content or configuration, can also leak information that aids an attacker in refining authentication attacks.
Consider an example where a token is issued with excessive permissions. An attacker who compromises a low-privilege user token might leverage weak authorization checks to access administrative endpoints. The combination of a predictable JWT secret, long-lived tokens, and missing authorization checks on sensitive routes can lead to complete account compromise.
During a middleBrick scan, these issues are detected by correlating unauthenticated endpoint analysis with Bearer Token usage patterns. The scanner checks for weak token configurations, missing rate limiting, and improper authorization enforcement. Findings include recommendations to rotate secrets, enforce MFA, and scope tokens tightly.
Bearer Tokens-Specific Remediation in Strapi
Remediation focuses on secure token lifecycle management, strict authorization, and defense-in-depth. The following practices and code examples illustrate how to harden Strapi when using Bearer Tokens.
1. Secure Token Configuration
Ensure the JWT secret is strong and rotated periodically. Override the default secret in ./config/jwt.js:
// ./config/jwt.js
module.exports = {
secret: process.env.JWT_SECRET || 'a-very-long-random-string-generated-using-crypto-random-bytes-32-chars-min',
expiresIn: '15m', // short-lived access tokens
};
Use environment variables to manage the secret and avoid committing it to version control. For refresh tokens, implement a separate, long-lived token stored in httpOnly cookies with strict SameSite and Secure flags.
2. Enforce HTTPS and Secure Transmission
Always serve Strapi behind HTTPS to protect Bearer Tokens in transit. In production, enforce secure cookies and transport security headers:
// Example middleware snippet to enforce HTTPS (not a full plugin)
if (process.env.NODE_ENV === 'production') {
app.use((ctx, next) => {
if (!ctx.secure) {
ctx.status = 403;
ctx.body = { error: 'HTTPS required' };
return;
}
return next();
});
}
Configure your reverse proxy (e.g., Nginx, Cloud Load Balancer) to terminate TLS and set Strict-Transport-Security headers.
3. Token Validation and Scope Checks
Leverage Strapi’s policies to validate scopes and roles on each request. For example, create a policy that ensures a token’s payload includes required roles before allowing access to admin routes:
// ./api/admin/policies/check-role.js
module.exports = async (ctx, next) => {
const user = ctx.state.user; // populated by Strapi's JWT middleware
if (!user || !user.roles || !user.roles.includes('admin')) {
ctx.status = 403;
ctx.body = { error: 'Insufficient permissions' };
return;
}
await next();
};
Apply this policy to sensitive routes in ./config/policies.js.
4. Rate Limiting and Account Protection
Enable rate limiting on authentication endpoints to mitigate brute-force attacks. Using a custom policy:
// ./api/auth/policies/rate-limit-auth.js
const rateLimit = require('koa-ratelimit').RateLimit;
const { default: MongooseStore } = require('rate-limit-mongoose');
module.exports = async (ctx, next) => {
const limiter = rateLimit({
driver: MongooseStore,
db: mongoose.connection,
duration: 15 * 60 * 1000, // 15 minutes
errorMessage: 'Too many attempts, try again later.',
identifier: ctx.request.ip,
max: 5, // 5 attempts
});
await limiter.check(ctx, next);
await next();
};
Apply this selectively to login and register endpoints.
5. Client-Side Storage Best Practices
If you must store Bearer Tokens in web applications, avoid localStorage due to XSS risks. Instead, use short-lived tokens and refresh them via secure, httpOnly cookies. For native clients, use platform-specific secure storage (e.g., Keychain, Keystore).
6. Continuous Monitoring and Scans
Use middleBrick to regularly scan your Strapi endpoints. The CLI allows you to integrate scans into scripts:
// Scan a Strapi instance from the terminal
middlebrick scan https://api.example.com
The dashboard tracks changes over time, and the GitHub Action can fail builds if the risk score drops below your chosen threshold, while the MCP Server lets you scan APIs directly from your IDE.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |