T09 · Insecure Skill Coding Practices
- Location
scripts/morning-push.js:120- Finding
Stored Prompt Injection Through Unvalidated User Profile Fields
- Content
View full analysis
k.trim()).filter(Boolean) : []; const fp = path.join(USERS_DIR, `${userId}.json`); const existing = fs.existsSync(fp) ? JSON.parse(fs.readFileSync(fp, 'utf8')) : {}; ``` The persisted values are subsequently inserted directly into agent-facing morning-push instructions: ```js return `[Career News Morning Push | user: ${user.userId} | profession: ${profession}${tag} | lang: en | region: ${region} | ${dateStr}] Please search and compile a morning news brief for this user. Profession: ${cfg.label} Search keywords: ${cfg.keywords.join(', ')}${extraKeywords ? ', ' + extraKeywords : ''} Priority sources: ${cfg.sources.join(', ')} Region focus: ${region.toUpperCase()} ``` The instant-query prompt contains the same unsafe interpolation pattern: ```js console.log(`[Career News Query | profession: ${profession} | lang: en | region: ${region.toUpperCase()} | ${dateStr}] Please find the latest news for a ${cfg.label} professional right now. Keywords: ${allKw.join(', ')} Priority sources: ${cfg.src.join(', ')} Region: ${region.toUpperCase()} ``` The profession-suggestion prompt also embeds stored region data: ```js console.log(`[Career News — Profession Suggestion | user: ${user.userId}] This user's current profession subscriptions: ${allProfs.join(', ')} Primary profession: ${user.profession} Region: ${user.region || 'cn'} Available professions to add: ${available.join(', ...[truncated 2428 chars]- Remediation
View remediation
