T09 · Insecure Skill Coding Practices
- Location
src/BudgetManager.ts:153- Finding
Non-Finite Numeric Values Can Bypass Budget Enforcement and Corrupt Usage Accounting
- Content
View full analysis
1) { throw new Error("warningThreshold must be within (0, 1]."); } } ``` ```ts // src/CostCalculator.ts:12-17 setPricing(model: string, pricing: ModelPricing): void { if (pricing.inputCostPerMillion < 0 || pricing.outputCostPerMillion < 0) { throw new Error("Pricing values must be non-negative."); } this.pricing.set(model, pricing); } ``` ```ts // src/UsageTracker.ts:265-276 private validateUsage(input: UsageEventInput): void { if (!input.sessionId.trim()) { throw new Error("sessionId is required."); } if (!input.model.trim()) { throw new Error("model is required."); } if (input.promptTokens < 0 || input.completionTokens < 0) { throw new Error("Token counts must be non-negative."); } } ``` ### Technical Analysis The validation relies exclusively on relational comparisons. In JavaScript, comparisons involving `NaN` return `false`. Consequently, values such as `NaN` pass all of the following checks: - `NaN <= 0` - `NaN < 0` - `NaN > 1` The implementation also does not reject positive or negative infinity, fractional token counts, or integers beyond the safe integer range. The most security-relevant result occurs in budget evaluation: ```ts const usageRatio = spentUsd / policy.limitUsd; let status: BudgetEvaluation["status"] = "ok"; if (usageRatio >= 1) { status = "exceeded"; } else ...[truncated 2218 chars]- Remediation
View remediation
1 ) { throw new Error("warningThreshold must be a finite number within (0, 1]."); } ``` 2. Require token counts to be finite, non-negative safe integers: ```ts const validTokenCount = (value: number): boolean => Number.isFinite(value) && Number.isSafeInteger(value) && value >= 0; if ( !validTokenCount(input.promptTokens) || !validTokenCount(input.completionTokens) ) { throw new Error("Token counts must be non-negative safe integers."); } ``` 3. Validate pricing values before storing them: ```ts if ( !Number.isFinite(pricing.inputCostPerMillion) || !Number.isFinite(pricing.outputCostPerMillion) || pricing.inputCostPerMillion < 0 || pricing.outputCostPerMillion < 0 ) { throw new Error("Pricing values must be finite and non-negative."); } ``` 4. Validate calculated costs before inserting records. Reject non-finite or negative results returned by a custom `costCalculator`. 5. Make budget evaluation fail closed. If the limit, spend, or calculated ratio is non-finite, throw an error or return an explicit invalid-policy status rather than `"ok"`. 6. Add database-level constraints where practical, such as non-negative token and cost checks, to provide defense in depth. 7. Add tests covering: - `NaN` - `Infinity` and `-Infinity` - Fractional token counts - Values exceeding `Number.MAX_SAFE_INTEGER` - Non-finite custom calculator results - Invalid budget values producing an error rather than `"ok"` ]]>
