Api Key Exposure in Strapi with Session Cookies
Api Key Exposure in Strapi with Session Cookies — how this specific combination creates or exposes the vulnerability
Strapi is a headless CMS that commonly uses session-based authentication. When an API key is embedded in client-side code or requests and session cookies are also present, the combination can unintentionally expose privileged operations to unauthenticated or partially authenticated contexts. This occurs when frontend JavaScript includes both a static API key (for third-party integrations or service-to-service patterns) and session cookies (typically managed by the browser for authenticated users), and those requests are accepted by Strapi endpoints without strict origin or channel validation.
In a black-box scan, middleBrick tests unauthenticated attack surfaces and checks for data exposure across channels. If an endpoint accepts session cookies but does not enforce strict same-site cookie policies, secure flags, or origin checks, an API key that should be stored server-side may be reflected in responses, logged, or exposed via CORS misconfigurations. For example, a request that includes a session cookie and an API key header might trigger a debug route or an overly permissive controller action that returns configuration or environment details, inadvertently leaking the key.
The risk is amplified when Strapi plugins or custom controllers inadvertently propagate API keys into logs, error messages, or JSON responses that are accessible over HTTP. Even if the application uses sessions to gate UI access, an API key exposed in these channels can be harvested by an attacker who can observe or intercept requests, especially if encryption is not enforced consistently across all endpoints. middleBrick’s checks for Data Exposure, Encryption, and Unsafe Consumption are designed to surface these patterns by correlating runtime behavior with OpenAPI specifications, identifying where headers or cookies contribute to unintended information leakage.
Consider an endpoint that accepts both a cookie-based session and an X-API-Key header. If the endpoint is intended for authenticated users only but does not validate that the session and the key belong to the same trust boundary, an attacker might supply a valid session cookie and observe responses that include key-related data. This violates the principle of channel separation and can lead to privilege escalation or unauthorized integration use. The LLM/AI Security checks in middleBrick additionally probe for indirect leakage by testing whether system prompts or configuration details can be coaxed from endpoints that mistakenly treat API keys as session-level credentials.
Because Strapi can serve both admin panels and public APIs, it is crucial to ensure that API keys are never co-located with session cookies in a way that allows cross-context exposure. The scanner validates whether endpoints that return sensitive data enforce strict transport security, proper cookie attributes (HttpOnly, Secure, SameSite), and correct authorization checks independent of channel presence. By aligning runtime findings with the OpenAPI spec and flagging inconsistencies, middleBrick helps identify specific vectors where the combination of session cookies and exposed API keys creates a breach path.
Session Cookies-Specific Remediation in Strapi — concrete code fixes
Remediation centers on ensuring that session cookies are handled securely and that API keys are never exposed to client-side code or logged in responses. Configure Strapi to set strict cookie attributes and enforce channel separation between cookie-based sessions and key-based authentication.
Secure cookie configuration in Strapi
Adjust your Strapi server options to enforce HttpOnly, Secure, and SameSite attributes. This prevents JavaScript access and ensures cookies are only sent over HTTPS.
// ./src/admin/config/middle.js
module.exports = ({ env }) => ({
settings: {
session: {
cookie: {
httpOnly: true,
secure: env('NODE_ENV') === 'production',
sameSite: 'strict',
path: '/',
},
},
},
});
For custom routes or admin extensions, explicitly validate origin and referer headers where appropriate, and avoid echoing API keys or secrets in response bodies. Ensure that any server-side logic that uses API keys keeps them out of logs and error traces.
Middleware to strip keys from client responses
Implement a Strapi middleware hook to remove or mask sensitive headers before responses leave the server. This prevents accidental exposure of keys via debug endpoints or misconfigured CORS rules.
// ./src/middlewares.js
module.exports = (config, { strapi }) => {
return async (ctx, next) => {
await next();
// Remove any accidental exposure of server-side headers
ctx.response.remove('X-API-Key');
ctx.response.remove('Authorization');
};
};
Enforce channel separation in controllers
In custom controllers, ensure that actions requiring API keys do not rely on session cookies for authorization unless trust boundaries are clearly defined. Use explicit service accounts with scoped permissions rather than mixing session identity with integration keys.
// ./src/api/protected/controllers/protected.js
'use strict';
module.exports = {
async sensitiveAction(ctx) {
const sessionUser = ctx.state.user;
// Do not use session identity to gate API key usage; validate scope separately
if (!sessionUser) {
ctx.unauthorized('Session required');
return;
}
// Use a server-side service key stored in environment variables
const serviceKey = process.env.SERVICE_API_KEY;
// Perform action using serviceKey without exposing it
const result = await strapi.entityService.findMany('api::data.record', {
filters: { ownerId: sessionUser.id },
});
ctx.send({ data: result });
},
};
Additionally, review plugin configurations and ensure that any third-party integrations do not inadvertently propagate API keys through query strings or logs. middleBrick’s CLI can be used to validate these configurations by scanning endpoints and checking for insecure cookie practices or improper header handling. The GitHub Action can enforce that any deployment with risky cookie or header behavior fails the build, while the MCP Server allows you to run on-demand checks from your IDE as you develop.