HIGH session fixationfeathersjsapi keys

Session Fixation in Feathersjs with Api Keys

Session Fixation in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability

Session fixation in a FeathersJS application that uses API keys occurs when an attacker forces a known session identifier onto a user or service and then leverages a valid API key to access authenticated endpoints. FeathersJS does not manage sessions by default, but if you add session support (for example via express-session) and also protect routes with API key validation, misalignment between session establishment and API key usage can create a path for fixation.

Consider a typical setup where a request must present an API key in a header (e.g., x-api-key) and, optionally, a session cookie is also present. If the server creates or accepts a session ID before validating the API key, an attacker can craft a request with a chosen session ID and a valid API key. Because the API key is treated as the primary credential while the session ID is trusted once established, the server may associate the authenticated API key with the attacker-chosen session. Later, the attacker can reuse that session ID—along with the same API key—to hijack the authenticated context, effectively fixing the session around the victim’s or attacker’s identifier.

This risk is compounded when API keys are long-lived and used across multiple requests without additional binding to a per-request or per-session nonce. For example, an endpoint that relies only on the API key for authorization but still writes a session record can be tricked into binding that key to an attacker-controlled session. Compounding this, if the API key validation logic runs after session creation, the server may treat subsequent requests as valid even when the session was set maliciously. Real-world patterns include OAuth client sessions or custom token handlers where the API key is checked, but the session cookie is accepted implicitly if present.

From an OWASP perspective, this aligns with Broken Access Control and the broader API security testing categories middleBrick checks, such as Authentication and BOLA/IDOR. An attacker does not need to break the API key itself; they exploit the interaction between session management and key validation to fixate a session and escalate privileges or maintain access across multiple user contexts.

Api Keys-Specific Remediation in Feathersjs — concrete code fixes

To mitigate session fixation when using API keys in FeathersJS, ensure that session creation (if used) occurs only after successful API key validation and that the session is bound to a value derived from the key or request context. Avoid accepting or setting a session identifier before verifying the caller’s authorization. Below are concrete code examples demonstrating a secure approach.

First, a minimal FeathersJS service that validates an API key on each request and only then attaches a securely derived session identifier. This uses a custom hook to check the header and explicitly set a session ID that is tied to the key, preventing external fixation:

const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const session = require('express-session');

const app = express(feathers());

// Configure session middleware with secure defaults
app.configure(session({
  secret: process.env.SESSION_SECRET || 'change-this-to-a-strong-secret',
  resave: false,
  saveUninitialized: false,
  cookie: { secure: process.env.NODE_ENV === 'production', httpOnly: true, sameSite: 'strict' }
}));

// API key validation hook (run before session creation or usage)
const validateApiKey = context => {
  const provided = context.headers['x-api-key'];
  const expected = process.env.API_KEY; // store securely, e.g., from env/secrets manager
  if (!provided || provided !== expected) {
    throw new Error('Unauthorized');
  }
  // Bind session to the key hash instead of accepting an existing session ID
  const crypto = require('crypto');
  const binding = crypto.createHash('sha256').update(provided).digest('hex');
  context.result = context.result || {};
  context.result.sessionBinding = binding;
  return context;
};

// Apply the hook and then safely use session if needed
app.hooks({
  before: {
    all: [validateApiKey]
  }
});

// A sample protected route
app.get('/secure', (context) => {
  // At this point, API key is validated and sessionBinding is set
  const binding = context.result.sessionBinding;
  // You may store binding in session if you need server-side session tracking
  if (context.req.session) {
    context.req.session.binding = binding;
  }
  return { message: 'Access granted', binding };
});

app.listen(3030);

If you prefer to rely solely on API keys without sessions, disable session usage for those routes entirely and ensure no session cookie is created or expected. This eliminates the fixation surface by removing the session as an authorization factor:

const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');

const app = express(feathers());

// No session middleware used

const requireApiKey = context => {
  const key = context.headers['x-api-key'];
  if (key !== process.env.API_KEY) {
    throw new Error('Unauthorized');
  }
  return context;
};

app.hooks({ before: { all: [requireApiKey] } });

app.get('/api/resource', () => ({ data: 'protected' }));

app.listen(3030);

In both patterns, avoid setting or accepting a session ID before API key validation. If you must use sessions, bind them explicitly to the validated key material and do not trust incoming session identifiers. These practices reduce the risk of session fixation and align with the checks performed by middleBrick’s Authentication and BOLA/IDOR scans, which can surface misconfigurations in how identifiers and credentials interact.

Frequently Asked Questions

Can middleBrick detect session fixation issues in FeathersJS APIs that use API keys?
middleBrick’s Authentication and BOLA/IDOR checks can surface indicators such as missing binding between credentials and sessions, but detailed exploit confirmation requires manual review and testing alongside your application logic.
Should I use sessions at all if my FeathersJS API relies on API keys?
If you use API keys as the primary credential, you can safely avoid sessions entirely. If sessions are required, bind them to a hash of the validated API key and perform key validation before any session creation or modification.