T09 · Insecure Skill Coding Practices
- Location
scripts/irr.py:25- Finding
Unvalidated Numeric Inputs Allow Process Crashes, Resource Exhaustion, and Invalid Financial Results
- Content
View full analysis
float: lo, hi = 0.0, 1.0 for _ in range(200): mid = (lo + hi) / 2 pv = sum(pay_per_month / (1 + mid) ** k for k in range(1, months + 1)) if pv > principal: lo = mid else: hi = mid return (lo + hi) / 2 ``` ```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 * 100 ``` ```python 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])) elif a[0] == "daily" and len(a) == 2: wan = float(a[1]) ``` ### Technical Analysis Command-line values are converted to `float` or `int` but are not checked for valid financial ranges, finiteness, or reasonable size. In particular: - A period count of zero causes division by zero when calculating the payment. - A principal of zero causes division by zero when calculating the displayed surface rate. - An extremely large period count causes the IRR function to perform approximately `200 × months` iterations through the inner generator, enabling excessive CPU consumption. - Negative principal, period, fee, or rate values can produce nonsensical financial output. - Floating-point values such as `NaN` and infinity are accepted by `float()` and can propagate into misleading results. - Arithmetic exceptions such as `ZeroDivisionError` and `OverflowError` are not covered by the existing `ValueError` handler. The issue is reachable directly through ...[truncated 1925 chars]- Remediation
View remediation
0`. - Require `months > 0`. - Require fees and rates to be nonnegative unless negative values are explicitly supported. - Use `math.isfinite()` to reject `NaN` and positive or negative infinity. 2. Impose a practical upper bound on the period count, such as 600 or another documented business limit, before entering the IRR loop. 3. Reject values outside realistic financial ranges with a clear error message and nonzero exit status. 4. Catch expected arithmetic failures, including `ZeroDivisionError` and `OverflowError`, while retaining validation as the primary defense. 5. Consider replacing the period-by-period summation with the closed-form present-value formula for an annuity. This makes calculation time independent of the number of periods and further reduces denial-of-service exposure. 6. Add regression tests covering: - Zero and negative principal. - Zero and negative periods. - Excessively large periods. - Negative fees and rates. - `NaN` and infinity. - Extremely large finite values. - Valid boundary values. ]]>
