T09 · Insecure Skill Coding Practices
- Location
src/lib/storage.ts:44- Finding
Path Traversal Through Unvalidated Date Values Permits JSON File Access Outside the Log Directory
- Content
View full analysis
(logPath(date), []); } export function writeDayLog(date: string, log: DayLog): void { writeJson(logPath(date), log); } ``` The caller only verifies that the date and time values are present: ```ts function requireDate(args: Args): string { const d = args['date'] as string | undefined; if (!d) { err('--date YYYY-MM-DD is required'); process.exit(1); } return d; } function requireTime(args: Args): string { const t = args['time'] as string | undefined; if (!t) { err('--time HH:MM is required'); process.exit(1); } return t; } ``` A meal operation subsequently uses the unvalidated date: ```ts async function mealAdd(args: Args): Promise { const date = requireDate(args); const time = requireTime(args); const name = args['name'] as string | undefined; if (!name) { err('--name is required'); process.exit(1); } const id = nanoid(8); const meal: Meal = { id, time, name, ingredients: [] }; const log = readDayLog(date); log.push(meal); writeDayLog(date, log); await upsertVector(mealVecId(id), name, { type: 'meal', mealId: id, date }); print({ id }); } ``` ### Technical Analysis The command documentation specifies dates in `YYYY-MM-DD` format, but `requireDate()` only checks whether a value is present. It does not validate the date syntax, reject path separators, or verify that the resolved path remains under `LOGS_DIR`. `logPath()` concatenates the attacker-controlled value with `.json` and passes it to `path.join()`. A value containing `../` ...[truncated 2200 chars]- Remediation
View remediation
