T09 · Insecure Skill Coding Practices
Note
- Location
- scripts/monitor.js:7
- Finding
- Unchecked command-line arguments allow monitor denial of service and status-output spoofing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.js`, lines 7–18 and 29–42 **Vulnerability Type**: Unvalidated numeric input and unsanitized terminal/Markdown output **Risk Level**: Low ### Vulnerable Code ```javascript if (args.length < 3) { console.log("Usage: node monitor.js <current_tokens> <max_tokens> <current_model> [quota_remaining_percent]"); process.exit(1); } const current = parseInt(args[0], 10); const max = parseInt(args[1], 10); const model = args[2]; const quota = args[3] || "N/A"; const ratio = (current / max); const percent = Math.round(ratio * 100); // Generate progress bar const barLength = 10; const filledLength = Math.round(ratio * barLength); const bar = "▓".repeat(Math.min(filledLength, barLength)) + "░".repeat(Math.max(0, barLength - filledLength)); ``` ```javascript if (ratio >= 0.95) { riskLevel = "緊急 (Critical)"; color = "🔴"; } else if (ratio >= 0.85) { riskLevel = "警告 (Warning)"; color = "🟡"; } console.log(` --- ### 🛡️ Token Guard 狀態回報 **【風險等級:${riskLevel} ${color}】** - **目前模型:** ${model} - **上下文負載:** \`[${bar}] ${percent}%\` - **剩餘配額:** ${quota}% **⚠️ 診測建議:** ${ratio >= 0.85 ? "建議立即執行 /compact 或換模型以免中斷。" : "目前尚在安全範圍,請繼續任務。"} --- `); ``` ### Technical Analysis The script checks only the number of arguments. It does not verify that `current` and `max` are finite numbers, that `current` is non-negative, or that `max` is greater than zero. A negative `current` value can produce a negative `filledLength`. That value is passed to `String.prototype.repeat()` when constructing the unfilled portion of the progress bar, resulting in a `RangeError` and termination of the monitoring process. Zero, nonnumeric, infinite, or otherwise malformed values can also produce invalid ratios and misleading status calculations. The `model` and `quota` arguments are inserted directly into a formatted terminal and Markdown report. If these values originate from an attacker-controlled or unreliable integratio ...[truncated 1416 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse numeric arguments with `Number()` and reject values for which `Number.isFinite()` is false. 2. Require `current` to be non-negative and `max` to be strictly greater than zero. 3. If quota is numeric, enforce an expected range such as `0` through `100`; otherwise, permit only a fixed safe placeholder. 4. Reject invalid arguments with a concise error message and a nonzero exit status before performing ratio or progress-bar calculations. 5. Clamp the calculated ratio and progress-bar lengths to safe ranges before calling `String.repeat()`. 6. Remove ANSI and other terminal-control characters from `model` and `quota`. 7. Escape Markdown metacharacters and normalize or reject line breaks before interpolating external text into the report. 8. Add tests covering negative values, zero maximum, nonnumeric values, extreme numbers, embedded newlines, Markdown injection, and ANSI escape sequences. Example validation pattern: ```javascript const current = Number(args[0]); const max = Number(args[1]); if ( !Number.isFinite(current) || !Number.isFinite(max) || current < 0 || max <= 0 ) { console.error("Invalid token values: current must be non-negative and max must be positive."); process.exit(1); } const ratio = current / max; const displayRatio = Math.max(0, Math.min(ratio, 1)); const filledLength = Math.max( 0, Math.min(barLength, Math.round(displayRatio * barLength)) ); function sanitizeDisplay(value) { return String(value) .replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "") .replace(/[\r\n]/g, " ") .replace(/([\\`*_{}[\]()#+.!|>~-])/g, "\\$1"); } ``` ]]>
