T09 · Insecure Skill Coding Practices
- Location
scripts/irr.py:37- Finding
Missing Validation for Financial Input Parameters
- Content
View full analysis
Vulnerability Details
File Location:
scripts/irr.py, lines 37-41 and 54-59
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: MediumVulnerable Code
python def show(principal: float, months: int, total_fee: float) -> None: pay = (principal + total_fee) / months r = irr_monthly(principal, months, pay) apr = r * 12 * 100 surface = total_fee / principal / months * 12 * 100python if a[0] == "fee" and len(a) == 4: p, n, rate = float(a[1]), int(a[2]), float(a[3]) / 100 show(p, n, p * rate * n) elif a[0] == "total" and len(a) == 4: show(float(a[1]), int(a[2]), float(a[3]))Technical Analysis
Values supplied through command-line arguments are converted to numeric types but are not checked against valid financial constraints. In particular:
principalis not required to be greater than zero.monthsis not required to be a positive integer.- Fees and rates can be negative.
- Floating-point values such as
NaNand positive or negative infinity are accepted byfloat(). - Arithmetic exceptions are not handled because the exception handler only catches
ValueError.
A zero principal causes division by zero when calculating
surface. A zero installment count causes division by zero when calculating bothpayandsurface. Negative and non-finite values may propagate through the IRR calculation and produce nonsensical or misleading financial results instead of a validation error.Attack Path
- An attacker, user, or upstream agent supplies an invalid calculator request.
- For example, the process is invoked with
python3 scripts/irr.py fee 12000 0 0.6orpython3 scripts/irr.py fee 0 12 0.6. - The arguments successfully pass numeric conversion.
show()divides bymonthsorprincipal.- An uncaught
ZeroDivisionErrorterminates the process.
Alternatively, an invocation such as `python3 sc ...[truncated 615 chars]
- Remediation
View remediation
Remediation Suggestions
- Require
principalto be finite and strictly greater than zero. - Require
monthsto be a positive integer and impose a reasonable upper bound. - Require the fee and periodic rate to be finite and nonnegative unless negative-cost financing is intentionally supported.
- Validate the resulting monthly payment before invoking the solver.
- Reject
NaNand infinity explicitly withmath.isfinite(). - Catch expected arithmetic failures and return a clear error message with a nonzero exit status.
- Keep validation in a shared function so both
feeandtotalmodes enforce identical constraints. - Add automated tests covering zero, negative, non-finite, extremely large, and valid boundary values.
Example validation pattern:
python import math def validate_inputs(principal: float, months: int, total_fee: float) -> None: if not math.isfinite(principal) or principal <= 0: raise ValueError("Principal must be a finite value greater than zero") if months <= 0: raise ValueError("Months must be a positive integer") if not math.isfinite(total_fee) or total_fee < 0: raise ValueError("Total fee must be a finite nonnegative value")- Require
