Room ids pass a strict alphabet before touching the filesystem
The lazy room wake handed caller-supplied ids to fileFor; an 8-char traversal like '../../aa' fit through the length trim. Only [A-Z0-9] codes reach disk now — reads refuse quietly, server-minted writes fail loud. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
co-authored by
Claude Fable 5
parent
002698085f
commit
e83d70116f
@@ -75,7 +75,14 @@ export type RoomLine = RoomMetaLine | JoinLine | StartLine | CommandLine | ChatL
|
|||||||
|
|
||||||
const DATA_DIR = process.env.WIZWAR_DATA_DIR ?? join(process.cwd(), "data", "rooms");
|
const DATA_DIR = process.env.WIZWAR_DATA_DIR ?? join(process.cwd(), "data", "rooms");
|
||||||
|
|
||||||
|
/** Room ids reach the filesystem, so only the room-code alphabet may pass —
|
||||||
|
* anything else (dots, slashes, control bytes) is a traversal attempt. */
|
||||||
|
function safeRoomId(roomId: string): boolean {
|
||||||
|
return /^[A-Z0-9]{1,8}$/.test(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
function fileFor(roomId: string): string {
|
function fileFor(roomId: string): string {
|
||||||
|
if (!safeRoomId(roomId)) throw new Error(`unsafe room id: ${JSON.stringify(roomId)}`);
|
||||||
return join(DATA_DIR, `${roomId}.jsonl`);
|
return join(DATA_DIR, `${roomId}.jsonl`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +97,7 @@ export function ensureDataDir(): void {
|
|||||||
|
|
||||||
/** A room file may exist even when the room failed to restore into memory. */
|
/** A room file may exist even when the room failed to restore into memory. */
|
||||||
export function roomFileExists(roomId: string): boolean {
|
export function roomFileExists(roomId: string): boolean {
|
||||||
return existsSync(fileFor(roomId));
|
return safeRoomId(roomId) && existsSync(fileFor(roomId));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function appendLine(roomId: string, line: RoomLine): void {
|
export function appendLine(roomId: string, line: RoomLine): void {
|
||||||
@@ -99,6 +106,7 @@ export function appendLine(roomId: string, line: RoomLine): void {
|
|||||||
|
|
||||||
/** Read one persisted room's lines, or null if it has no ledger. */
|
/** Read one persisted room's lines, or null if it has no ledger. */
|
||||||
export function readRoom(roomId: string): RoomLine[] | null {
|
export function readRoom(roomId: string): RoomLine[] | null {
|
||||||
|
if (!safeRoomId(roomId)) return null;
|
||||||
const file = fileFor(roomId);
|
const file = fileFor(roomId);
|
||||||
if (!existsSync(file)) return null;
|
if (!existsSync(file)) return null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user