T09 · Insecure Skill Coding Practices
- Location
lib/dice.mjs:45- Finding
Unbounded Dice Count Enables Local Resource Exhaustion
- Content
View full analysis
{ const trimmed = String(expr).trim(); if (/^-?\d+$/.test(trimmed)) { return { spec: trimmed, total: parseInt(trimmed, 10), fixed: true }; } return rollDice(trimmed, rng); }; ``` ### Technical Analysis The dice-expression parser accepts an arbitrary sequence of digits for the dice count and does not enforce an upper bound. `rollDice()` then performs one random-number operation and one array insertion for every requested die. An input such as `1000000000d6` therefore attempts to execute one billion loop iterations while retaining one billion roll results in memory. This can consume all available CPU and heap memory, trigger garbage-collection pressure, terminate the Node.js process with an out-of-memory error, or make the host unresponsive. The issue is directly exposed by ...[truncated 1894 chars]- Remediation
View remediation
MAX_DICE_COUNT) { throw new Error(`Dice count must be between 1 and ${MAX_DICE_COUNT}`); } if (!Number.isSafeInteger(sides) || sides < 1 || sides > MAX_DICE_SIDES) { throw new Error(`Dice sides must be between 1 and ${MAX_DICE_SIDES}`); } if ( !Number.isSafeInteger(multiplier) || multiplier < 1 || multiplier > MAX_MULTIPLIER ) { throw new Error("Dice multiplier is outside the permitted range"); } if ( !Number.isSafeInteger(modifier) || Math.abs(modifier) > MAX_ABSOLUTE_MODIFIER ) { throw new Error("Dice modifier is outside the permitted range"); } ``` 2. Apply the same validated parser to every dice-input path, including SAN success and failure loss expressions. Do not maintain separate permissive parsing logic. 3. Reject values that are not safe integers. This prevents very large decimal strings from producing imprecise or non-finite JavaScript numbers. 4. Limit output size independently of computation. If high dice counts are legitimately required, calculate the total incrementally and retain only a bounded sample instead of storing every roll. 5. When invoked by an agent or server, add defense-in-depth controls such as execution timeouts, memory limits, worker-process isolation, and maximum command-length limits. 6. Add regression tests for boundary and abusive inputs, including: - The maximum accepted dice count. - One count above the maximum. - Extremely long numeric counts. - Excessive side counts, multipliers, and modifiers. - Malicious expressions supplied through both `roll` and `san check`. ]]>
