T09 · Insecure Skill Coding Practices
- Location
expense-tracker.js:66- Finding
Unvalidated monetary input permits persistent financial data corruption
- Content
View full analysis
Vulnerability Details
File Location:
expense-tracker.js, lines 66-73
Vulnerability Type: Improper numeric input validation
Risk Level: Mediumjs const expense = { id: Date.now(), description, amount: parseFloat(amount), category, notes, date: new Date().toISOString() }; data.expenses.push(expense);Technical Analysis
The application converts the supplied amount with
parseFloat()but does not verify that the result is finite, positive, within an acceptable range, or represented by a strictly numeric input string.Consequently:
- Inputs such as
abcproduceNaN. - Inputs such as
Infinityproduce a non-finite value. - Inputs such as
12abcare silently interpreted as12. - Negative values are accepted and reduce calculated expense totals.
- When serialized with
JSON.stringify(),NaNandInfinitybecomenull.
The malformed value is added to the expense collection and subsequently persisted by
saveData(). A persistednullamount can also cause runtime failures in display operations that callexpense.amount.toFixed(2).Attack Path
- An attacker or untrusted caller invokes the expense command with a crafted amount, such as
abc,Infinity,-500, or12abc. parseFloat()producesNaN, a non-finite number, a negative number, or a partially parsed number.- The application adds the resulting record without validation.
saveData()serializes and writes the malformed record todata/expenses.json.- Later statistics, exports, or record-display operations produce inaccurate results or encounter a runtime exception.
Impact Assessment
Exploitation does not grant additional operating-system privileges or access outside the Skill directory. Its scope is the integrity and availability of the local expense-tracking data. An attacker able to supply expense commands can persist malformed records, man ...[truncated 124 chars]
- Inputs such as
- Remediation
View remediation
Remediation Suggestions
Parse and validate the amount before constructing or saving an expense:
js const normalizedAmount = String(amount).trim(); if (!/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/.test(normalizedAmount)) { throw new Error('Amount must be a valid non-negative number with at most two decimal places'); } const parsedAmount = Number(normalizedAmount); if (!Number.isFinite(parsedAmount) || parsedAmount <= 0 || parsedAmount > 1_000_000_000) { throw new Error('Amount is outside the permitted range'); }Store
parsedAmountonly after validation. The precise minimum, maximum, decimal precision, and policy for refunds or negative adjustments should be explicitly defined. The application should also validate every record loaded fromexpenses.jsonso that preexisting or externally modified malformed data cannot reach arithmetic or formatting operations.
