T09 · Insecure Skill Coding Practices
- Location
scripts/buddy.ts:23- Finding
Predictable Shared Temporary State Allows Cross-User Tampering and Symbolic-Link Attacks
- Content
View full analysis
; } function loadState(): BuddyState { try { if (!existsSync(STATE_FILE)) { return { muted: false }; } const data = readFileSync(STATE_FILE, 'utf-8'); return JSON.parse(data); } catch { return { muted: false }; } } function saveState(state: BuddyState): void { try { writeFileSync(STATE_FILE, JSON.stringify(state, null, 2)); } catch (e) { // Silently fail if can't write state } } ``` The saved-pet operation writes user-controlled state to the same global file: ```ts if (command === 'save') { const species = args[2] as any; // Optional species parameter const petName = args[3] as string || '小墨'; // Optional name parameter const pet = generatePerfectCompanion(species); pet.name = petName; const state = loadState(); state.savedPet = pet; saveState(state); ``` ### Technical Analysis The application stores all state in the fixed, globally predictable path `/tmp/buddy-state.json`. The filename does not incorporate `userId`, so every invocation and every user of the Skill reads and modifies the same state. The code does not: - Isolate state by user. - Validate file ownership or permissions. - Verify that the path refers to a regular file. - prevent symbolic-link traversal. - Use restrictive file creation permissions explicitly. - Create the file atomically. - Validate parsed JSON against a runtime schema. TypeScript interfaces do not validate data returned by `JSON.parse`. Consequently, a party able to modify the s ...[truncated 2224 chars]- Remediation
View remediation
