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.
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.
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.
finserv-session-security.session-lifecycle.timeout-configurableinfo"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"db/schema/ or prisma/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
}