T05 · Unauthorized Access and Privilege Escalation
- Location
index.ts:70- Finding
Path Traversal Through Unvalidated Session Identifiers
- Content
View full analysis
Vulnerability Details
File Location:
index.ts:70-91
Vulnerability Type: Path traversal and unauthorized filesystem access
Risk Level: HighVulnerable Code
ts const updatesPath = path.join(SESSIONS_PATH, `${sessionId}.updates`); if (!fs.existsSync(updatesPath)) return { success: false, error: "Session updates log not found" }; const binaryUpdate = Buffer.from(updatePayload, 'base64'); fs.appendFileSync(updatesPath, binaryUpdate);ts async function loadTeam(params: any) { const { sessionId } = params; const snapshotPath = path.join(SESSIONS_PATH, `${sessionId}.snapshot`); const updatesPath = path.join(SESSIONS_PATH, `${sessionId}.updates`);Technical Analysis
The caller-controlled
sessionIdis inserted into filesystem paths without validation or canonical containment checks.path.join()normalizes traversal segments but does not guarantee that the resulting path remains underSESSIONS_PATH.A value containing components such as
../can therefore escapedata/sessions. Theteam.syncaction can append data to an existing attacker-selected path whose final name ends in.updates. Theteam.loadaction can attempt to read attacker-selected.snapshotand.updatesfiles outside the session directory.The filename suffixes constrain the set of reachable files, but they do not prevent directory traversal or access outside the intended storage boundary.
Attack Path
- The attacker identifies an existing file outside
data/sessionsending in.updates, or places a compatible.snapshotfile in another accessible directory. - The attacker supplies a traversal identifier such as
../../targetassessionId. path.join()resolves the resulting path outsideSESSIONS_PATH.- For
team.sync, the attacker submits a signed payload and the application appends it totarget.updates. - For
team.load, the application readstarget.snapshot...[truncated 762 chars]
- The attacker identifies an existing file outside
- Remediation
View remediation
Remediation Suggestions
-
Validate
sessionIdagainst the exact server-generated format, for example^session-[0-9]+-[a-z0-9]{5}$. -
Reject path separators,
.components, encoded traversal sequences, null bytes, and unexpected characters. -
Resolve the final path and verify containment before every filesystem operation:
ts function sessionFile(sessionId: string, extension: string): string { if (!/^session-[0-9]+-[a-z0-9]{5}$/.test(sessionId)) { throw new Error("Invalid session ID"); } const root = path.resolve(SESSIONS_PATH); const candidate = path.resolve(root, `${sessionId}.${extension}`); if (!candidate.startsWith(root + path.sep)) { throw new Error("Session path escapes storage directory"); } return candidate; } -
Open files using restrictive flags and permissions where appropriate.
-
Run the service under a dedicated, least-privileged operating-system account.
-
Add tests covering
../, absolute paths, repeated separators, encoded traversal attempts, and platform-specific separators.
-
