T09 · Insecure Skill Coding Practices
Warning
- Location
- tools/generate_copy.js:76
- Finding
- Unbounded User-Controlled Generation Count Can Cause Resource Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `tools/generate_copy.js:76`, `tools/generate_copy.js:160`, `tools/generate_copy.js:224`, and `tools/generate_copy.js:244` **Vulnerability Type**: Uncontrolled resource consumption / local denial of service **Risk Level**: Medium ### Vulnerable Code ```javascript function generateTitles(product, count = 10, style = 'xiaohongshu') { const titles = []; const platform = PLATFORM_STYLES[style] || PLATFORM_STYLES.xiaohongshu; for (let i = 0; i < count; i++) { let template = TITLE_TEMPLATES[i % TITLE_TEMPLATES.length]; // Title generation omitted titles.push(title); } return titles; } ``` ```javascript function generateCTAs(count = 5) { const ctas = []; for (let i = 0; i < count; i++) { let template = CTA_TEMPLATES[i % CTA_TEMPLATES.length]; // CTA generation omitted ctas.push(cta); } return ctas; } ``` The counts are read directly from command-line arguments without range or finiteness validation: ```javascript case 'titles': { const product = args[1] || '产品'; const count = parseInt(args[2]) || 10; const style = args[3] || 'xiaohongshu'; const titles = generateTitles(product, count, style); console.log('📝 标题方案:\n'); titles.forEach((t, i) => console.log(`${i + 1}. ${t}`)); break; } ``` ```javascript case 'ctas': { const count = parseInt(args[1]) || 5; const ctas = generateCTAs(count); console.log('🎯 CTA 方案:\n'); ctas.forEach((c, i) => console.log(`${i + 1}. ${c}`)); break; } ``` ### Technical Analysis The `titles` and `ctas` commands accept a user-controlled count and pass it to loops that allocate one array element per iteration. There is no maximum permitted count, no `Number.isFinite` check, and no validation that the value is a safe positive integer. A sufficiently large finite value causes excessive CPU consumption and heap growth while the output array is constructed. If construction succeeds, printing every ...[truncated 1826 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Create a shared count-validation function and apply a conservative upper bound appropriate to each command: ```javascript function parseCount(value, defaultValue, maximum) { if (value === undefined) { return defaultValue; } const count = Number(value); if (!Number.isSafeInteger(count) || count < 1 || count > maximum) { throw new Error(`Count must be an integer between 1 and ${maximum}`); } return count; } ``` Use it for both affected commands: ```javascript const count = parseCount(args[2], 10, 100); // titles const count = parseCount(args[1], 5, 100); // CTAs ``` Additional hardening measures should include: 1. Catch validation errors and exit with a clear message and a nonzero status. 2. Apply limits inside `generateTitles` and `generateCTAs` as well as at the CLI boundary, so future programmatic callers cannot bypass validation. 3. Consider streaming generated entries directly rather than retaining the entire result in an array when large output is legitimately needed. 4. Run the utility with process memory, CPU, execution-time, and output-size limits when invoked by a service or agent. 5. Add tests for zero, negative values, non-numeric input, values above the maximum, `Infinity`, and integers outside JavaScript's safe range. ]]>
