Timeout configurable per org, min 15min
Why it matters
Different organizations within a multi-tenant financial platform have different risk tolerances and regulatory environments. A corporate treasury customer operating under SOC 2 Type II may be required to enforce shorter timeouts than a retail consumer. Hard-coding a global timeout at the application layer removes admin control and forces a binary choice: apply the strictest timeout everywhere and hurt UX, or apply a lenient one and fail to meet specific org-level compliance requirements. CWE-613 and PCI-DSS Req 8.2.8 do not preclude stricter controls — per-org configuration lets each tenant set a timeout at or below the maximum, enforcing the floor at the database level.
Severity rationale
Info severity because a hard-coded global timeout is not inherently insecure if it meets the 15-minute minimum, but the absence of per-org configuration prevents compliance-driven customers from enforcing stricter controls required by their own policies.
Remediation
Add an org_settings table with a database-enforced minimum constraint in db/schema/ or prisma/schema.prisma:
CREATE TABLE org_settings (
org_id UUID PRIMARY KEY REFERENCES organizations(id),
session_timeout_minutes INT NOT NULL
CHECK (session_timeout_minutes >= 15), -- enforce floor
updated_at TIMESTAMPTZ DEFAULT now()
);
Then read the org-specific value in session middleware before applying the timeout:
async function getSessionTimeout(orgId: string): Promise<number> {
const settings = await db.orgSettings.findUnique({ where: { org_id: orgId } });
return (settings?.session_timeout_minutes ?? 30) * 60 * 1000; // ms
}
The CHECK constraint prevents any org admin from setting a timeout below 15 minutes, even via direct DB access.
Detection
- ID:
timeout-configurable - Severity:
info - What to look for: Count all configuration mechanisms for session timeout (admin settings, database schema, environment variables). Look for a minimum constraint of at least 15 minutes. Quote the actual configuration table or settings structure found. Enumerate per-org vs. global settings.
- Pass criteria: At least 1 per-org configuration mechanism exists for session timeout, with a minimum enforced value of at least 15 minutes. Report the count even on pass (e.g., "1 org_settings table with session_timeout_minutes column, CHECK constraint >= 15").
- Fail criteria: Timeout is globally hard-coded with 0 per-org configuration options, or minimum allowed timeout is less than 15 minutes.
- Skip (N/A) when: The application is single-tenant (not multi-org) — cite the actual tenant model found.
- Detail on fail:
"Session timeout hard-coded to 30 minutes — 0 per-org configuration mechanisms found"or"Org config allows timeouts as low as 5 minutes — below 15-minute minimum" - Remediation: Add org-level timeout configuration (in
db/schema/orprisma/schema.prisma):// database schema CREATE TABLE org_settings ( org_id UUID PRIMARY KEY, session_timeout_minutes INT CHECK (session_timeout_minutes >= 15), updated_at TIMESTAMP ); // In session middleware async function getSessionTimeout(orgId: string) { const settings = await db.orgSettings.findUnique({ where: { org_id: orgId } }); return settings?.session_timeout_minutes || 30; // default 30, min 15 }
External references
- cwe · CWE-613 — Insufficient Session Expiration
- pci-dss:4.0 · Req 8.2.8
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-session-security·automated