Concurrent sessions limited to 1, warning on new login
Why it matters
Unlimited concurrent sessions mean a stolen session token can be used in parallel with the legitimate user's session — the account owner has no indication the account is being accessed simultaneously from a different location. CWE-613 covers this under insufficient session expiration. PCI-DSS Req 8.2.8 and NIST AC-10 both address concurrent session controls. In financial applications, the attack pattern is: steal session token, establish parallel session, initiate transfer while the legitimate user is actively transacting and won't notice a concurrent login warning. Limiting concurrent sessions to one and notifying on new logins closes this window — the attacker's session either terminates or the user receives a warning.
Severity rationale
High because unlimited concurrent sessions allow a stolen token to establish a parallel, invisible session that can execute financial operations at the same time as the legitimate user with no signal to either party.
Remediation
Enforce the single-session limit in src/middleware/concurrentSessionCheck.ts by checking active session count on each new login and either terminating prior sessions or alerting the user:
export async function enforceSessionLimit(
userId: string,
currentSessionId: string
) {
const active = await db.sessions.findMany({
where: { userId, expiresAt: { gt: new Date() } }
});
if (active.length > 0) {
await notifyUser(userId, 'New login detected — prior session terminated.');
await db.sessions.updateMany({
where: { userId, id: { not: currentSessionId } },
data: { terminatedAt: new Date() }
});
}
}
Call enforceSessionLimit immediately after session creation in the login handler, before returning the session token to the client. Store sessions server-side (Redis or Postgres) so termination is authoritative — client-side token deletion alone is insufficient.
Detection
- ID:
concurrent-session-limit - Severity:
high - What to look for: Count all active session tracking mechanisms and quote the actual session limit setting found. Enumerate the enforcement logic: does a new login terminate or warn existing sessions? Verify the concurrent session limit is no more than 1 for financial operations. An unlimited concurrent session policy does not count as pass — do not pass if users can maintain more than 1 active session.
- Pass criteria: Concurrent session limit is enforced at no more than 1 active session per user for financial operations. When a new login occurs, the previous session is terminated or user is warned. Report the count even on pass (e.g., "Session limit: 1, previous session terminated on new login, warning notification sent").
- Fail criteria: Multiple concurrent sessions allowed (no limit enforced), or new login does not affect existing sessions, or limit exceeds 1 for financial contexts.
- Skip (N/A) when: The application does not require per-user session limits — cite the actual security requirements found.
- Detail on fail:
"No concurrent session limit — 0 enforcement mechanisms. User can maintain unlimited simultaneous sessions from different IPs." - Cross-reference: Check
finserv-session-security.concurrent-control.user-view-terminate-sessionsfor user session management, andfinserv-session-security.concurrent-control.login-location-trackingfor location awareness. - Remediation: Enforce single-session-per-user limit (in
src/middleware/concurrentSessionCheck.ts):// middleware/concurrentSessionCheck.ts export async function enforceSessionLimit(userId: string) { const activeSessions = await db.sessions.findMany({ where: { userId, expiresAt: { gt: new Date() } } }); if (activeSessions.length > 0) { // Notify user of new login attempt await notifyUser(userId, `New login from ${deviceInfo.location}`); // Option 1: Auto-terminate previous sessions await db.sessions.updateMany({ where: { userId, id: { not: currentSessionId } }, data: { terminatedAt: new Date() } }); } }
External references
- cwe · CWE-613 — Insufficient Session Expiration
- owasp:2021 · A07
- pci-dss:4.0 · Req 8.2.8
- nist:rev5 · AC-10 — Concurrent Session Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-session-security·automated