gristlabs_grist-core/app/common/BootProbe.ts

32 lines
791 B
TypeScript
Raw Permalink Normal View History

import { SandboxInfo } from 'app/common/SandboxInfo';
export type BootProbeIds =
'boot-page' |
'health-check' |
'reachable' |
'host-header' |
'sandboxing' |
'system-user' |
'authentication' |
Improve session ID security (#1059) Follow-up of #994. This PR revises the session ID generation logic to improve security in the absence of a secure session secret. It also adds a section in the admin panel "security" section to nag system admins when GRIST_SESSION_SECRET is not set. Following is an excerpt from internal conversation. TL;DR: Grist's current implementation generates semi-secure session IDs and uses a publicly known default signing key to sign them when the environment variable GRIST_SESSION_SECRET is not set. This PR generates cryptographically secure session IDs to dismiss security concerns around an insecure signing key, and encourages system admins to configure their own signing key anyway. > The session secret is required by expressjs/session to sign its session IDs. It's designed as an extra protection against session hijacking by randomly guessing session IDs and hitting a valid one. While it is easy to encourage users to set a distinct session secret, this is unnecessary if session IDs are generated in a cryptographically secure way. As of now Grist uses version 4 UUIDs as session IDs (see app/server/lib/gristSessions.ts - it uses shortUUID.generate which invokes uuid.v4 under the hood). These contain 122 bits of entropy, technically insufficient to be considered cryptographically secure. In practice, this is never considered a real vulnerability. To compare, RSA2048 is still very commonly used in web servers, yet it only has 112 bits of security (>=128 bits = "secure", rule of thumb in cryptography). But for peace of mind I propose using crypto.getRandomValues to generate real 128-bit random values. This should render session ID signing unnecessary and hence dismiss security concerns around an insecure signing key.
2024-06-25 19:43:25 +00:00
'websockets' |
'session-secret'
;
export interface BootProbeResult {
verdict?: string;
// Result of check.
// "success" is a positive outcome.
// "none" means no fault detected (but that the test is not exhaustive
// enough to claim "success").
// "fault" is a bad error, "warning" a ... warning, "hmm" almost a debug message.
status: 'success' | 'fault' | 'warning' | 'hmm' | 'none';
details?: Record<string, any>;
}
export interface BootProbeInfo {
id: BootProbeIds;
name: string;
}
export type SandboxingBootProbeDetails = SandboxInfo;