HIGH session fixationfeathersjsfirestore

Session Fixation in Feathersjs with Firestore

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

Session fixation occurs when an application assigns a user a session identifier before authentication and does not regenerate that identifier afterward. In a Feathersjs application using Firestore as the session store, the risk arises from how session identifiers are created, stored, and associated with user records.

Feathersjs does not enforce session regeneration on login by default. If the application relies on a session middleware (such as express-session) with a Firestore store, the session ID may be set on the client (for example, via a cookie) before the user authenticates. An attacker can force a known session ID onto a victim’s browser, often via a URL, an insecure link, or a malicious page. When the victim authenticates, the session record in Firestore is keyed to the attacker-chosen identifier, allowing the attacker to hijack the authenticated session.

With Firestore, the session document is typically stored with a document ID that matches the session ID. If the session ID is predictable or not rotated post-login, an attacker who knows the ID can read or modify the session document depending on Firestore security rules. For example, a session document might contain the user ID and a timestamp; if the attacker’s session ID maps to the same document structure, they can impersonate the user even after the user authenticates.

Additionally, if the Feathersjs service does not bind the session to additional context—such as IP address or user agent—an attacker who obtains a valid session ID can reuse it from different locations. Firestore security rules that are too permissive may allow read/write access to session documents based solely on document ID, which exacerbates the risk when the session ID is known or predictable.

To detect this pattern with middleBrick, you can run a scan against your Feathersjs API endpoint. The LLM/AI Security checks specifically probe for authentication and session handling weaknesses, including indicators of vulnerable session flows. The scanner maps findings to frameworks such as OWASP API Top 10 and provides remediation guidance without requiring credentials or setup.

Firestore-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on ensuring session identifiers are unpredictable, bound to the authenticated user, and rotated after login. Below are concrete code examples for a Feathersjs service using Firestore with express-session.

1. Configure express-session with Firestore store and secure options

Use a strong session store, set secure cookies, and enable cookie attributes to reduce exposure.

const session = require('express-session');
const FirestoreStore = require('connect-firestore')(session);

const sessionMiddleware = session({
  store: new FirestoreStore({
    projectId: 'your-project-id',
    dataset: 'default',
    collection: 'sessions',
    expires: 14 * 24 * 60 * 60 * 1000 // 14 days
  }),
  name: '__Host-sid',
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    maxAge: 14 * 24 * 60 * 60 * 1000
  }
});

app.use(sessionMiddleware);

2. Regenerate session on authentication

In your authentication hook, destroy the old session and create a new one to prevent fixation.

const { AuthenticationService } = require('@feathersjs/authentication');
const session = require('express-session');

class CustomAuthenticationService extends AuthenticationService {
  async create(data, params) {
    const result = await super.create(data, params);
    const context = this.app.context;

    if (context && context.params && context.params.req) {
      const req = context.params.params.req || context.params.req;
      if (req.session) {
        req.session.regenerate((err) => {
          if (err) throw err;
          req.session.userId = result.user.id;
          req.session.authenticated = true;
        });
      }
    }
    return result;
  }
}

app.use('/authentication', new CustomAuthenticationService({
  store: new FirestoreStore({/* options */}),
  entity: 'user',
  service: 'users'
}));

3. Bind sessions to user and enforce Firestore security rules

Structure session documents to include the user ID and enforce Firestore rules so users can only access their own session documents.

// Example Firestore security rule (pseudocode for rules clarity)
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /sessions/{sessionId} {
      allow read, write: if request.auth != null && request.auth.uid == request.resource.data.userId;
      allow read: if request.auth != null && request.auth.uid == resource.data.userId;
    }
  }
}

In your Feathersjs service, ensure the session document includes the user ID:

// When creating/updating session data manually if needed
const sessionData = {
  userId: user.id,
  lastAccess: new Date().toISOString()
};
await app.service('sessions').create(sessionData);

4. Middleware to validate session-user binding on each request

Add a hook to verify that the session document matches the authenticated user, mitigating the impact of a leaked session ID.

app.hooks({
  after: {
    all: [async context => {
      if (context.params && context.params.req && context.params.req.session) {
        const session = context.params.req.session;
        if (session.userId) {
          const sessionDoc = await app.service('sessions').get(session.id);
          if (!sessionDoc || sessionDoc.userId !== session.userId) {
            throw new Error('Session mismatch');
          }
        }
      }
      return context;
    }]
  }
});

By combining secure cookie attributes, session regeneration, strict Firestore security rules, and server-side validation, you reduce the attack surface for session fixation in a Feathersjs + Firestore stack. middleBrick’s scans can validate these controls by checking authentication flows and session handling; the LLM/AI Security checks can further probe for weaknesses in authentication logic and prompt injection risks in related services.

Frequently Asked Questions

How can I test if my Feathersjs app with Firestore is vulnerable to session fixation?
Run a scan with middleBrick against your API endpoint. The scanner performs unauthenticated checks and maps findings to frameworks like OWASP API Top 10. You can also manually test by forcing a known session ID (e.g., via a URL parameter) before login and verifying that the session is not regenerated after authentication.
Does fixing session fixation require changes to Firestore security rules?
Yes. Ensure session documents are only readable and writable by the authenticated user whose ID matches the document’s userId field. Combine this with secure session cookie settings and server-side session regeneration in Feathersjs hooks.