Api Key Exposure in Hapi with Session Cookies
Api Key Exposure in Hapi with Session Cookies — how this specific combination creates or exposes the vulnerability
When an Hapi application uses session cookies to carry or reference API keys, the risk of Api Key Exposure increases if session handling and transport protections are misconfigured. Hapi applications commonly store session identifiers in cookies, and if those identifiers are used to look up or embed actual API keys, the exposure surface expands beyond the server-side session store to the client-side cookie.
Hapi relies on its cookie-based session management to maintain state. If an API key is encoded into a session cookie without encryption or integrity protection, an attacker who can intercept or steal the cookie gains direct access to the key. This can happen over non-TLS connections or when the Secure flag is not enforced, allowing network sniffing or insecure transmission to expose the key.
Another vector involves cookie scope and path misconfiguration. If a session cookie is set for a broad path or a parent domain, API keys accessible through that cookie may be sent to unintended endpoints or subdomains, increasing the likelihood of exposure through logs, browser history, or cross-origin requests. Hapi’s cookie configuration must explicitly set the Path and Domain attributes narrowly to reduce this risk.
Additionally, weak regeneration practices can contribute to exposure. If an Hapi server reuses session identifiers across authentication events without invalidating previous cookies, an attacker with an old cookie may retain access to API keys associated with that session. Proper session rotation and invalidation on logout or privilege changes are essential controls to prevent continued exposure of embedded keys.
The interaction between session cookies and API keys also affects auditability. Because the cookie resides on the client, any leakage through browser extensions, insecure storage, or client-side logs can expose the associated key. Hapi applications should avoid placing raw API keys in cookies and instead use the cookie only as a session handle, keeping the key on the server and binding it securely to the session with strict access controls.
Session Cookies-Specific Remediation in Hapi — concrete code fixes
To mitigate Api Key Exposure when using session cookies in Hapi, apply strict cookie attributes and avoid storing sensitive material directly in the cookie. Use the cookie only as a session identifier and keep API keys on the server, associated with the session via a secure store.
// Secure Hapi session cookie configuration example
const Hapi = require('@hapi/hapi');
const iron = require('@hapi/iron');
const SECRET = process.env.COOKIE_SECRET;
const init = async () => {
const server = Hapi.server({
port: 4000,
host: 'localhost'
});
await server.register(require('@hapi/cookie'));
server.state('sessionId', {
ttl: 24 * 60 * 60 * 1000,
isSecure: true,
isHttpOnly: true,
isSameSite: 'strict',
path: '/api',
encoding: 'iron',
cipher: 'aes',
password: SECRET
});
server.route({
method: 'POST',
path: '/login',
handler: async (request, h) => {
const apiKey = await fetchApiKeyForUser(request.payload.username);
const sessionId = generateSessionId();
// Store API key server-side, associate with sessionId
await server.app.sessionStore.set(sessionId, { apiKey });
const encrypted = await iron.seal({ sessionId }, SECRET, { ttl: 24 * 60 * 60 * 1000 });
return h.response({ success: true }).state('sessionId', encrypted);
},
options: {
auth: false,
plugins: {
cookie: {
password: SECRET,
isSecure: true,
isHttpOnly: true,
isSameSite: 'strict',
path: '/api'
}
}
}
});
server.route({
method: 'GET',
path: '/data',
handler: async (request, h) => {
const payload = await iron.unseal(request.state.sessionId, SECRET, { ttl: 24 * 60 * 60 * 1000 });
const session = await server.app.sessionStore.get(payload.sessionId);
if (!session) {
throw Boom.unauthorized('Invalid session');
}
// Use server-side API key, never send it to the client
return { data: fetchSensitiveData(session.apiKey) };
},
options: {
auth: false,
plugins: {
cookie: {
password: SECRET
}
}
}
});
await server.start();
};
const generateSessionId = () => require('crypto').randomBytes(16).toString('hex');
module.exports = { init };
Key remediation practices in this example include:
- Setting
isSecure: trueto ensure cookies are only sent over HTTPS, preventing exposure on insecure networks. - Using
isHttpOnly: trueto protect the cookie from JavaScript access, reducing the impact of XSS. - Applying
isSameSite: 'strict'to limit cookie transmission to first-party contexts, mitigating CSRF risks. - Restricting the cookie
pathto/apiso the session identifier is not sent to unrelated routes where exposure could be broader. - Encrypting the session identifier with
@hapi/ironand storing the actual API key server-side, never placing the key directly in the cookie.
For teams using the middleStack ecosystem, the CLI can be integrated into scripts to validate cookie-related security headers and configurations, while the GitHub Action can add API security checks to your CI/CD pipeline to fail builds if risky cookie practices are detected. The Dashboard helps track these settings across environments, and the MCP Server allows you to scan APIs directly from your AI coding assistant to surface insecure cookie patterns during development.