T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/calculate_backpay.py:187
- Finding
- Insufficient Input Validation Enables Denial of Service and Invalid Financial Calculations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/calculate_backpay.py:187-207` and `scripts/calculate_backpay.py:405-412` **Vulnerability Type**: Improper input validation and uncontrolled loop **Risk Level**: Medium ### Vulnerable Code ```python if start_year < BACKPAY_YEAR_MIN or (end_year > BACKPAY_YEAR_MAX or (end_year == BACKPAY_YEAR_MAX and end_month > 12)): raise ValueError( f"补缴时段仅支持 {BACKPAY_YEAR_MIN} 年 1 月至 {BACKPAY_YEAR_MAX} 年 12 月," f"{BACKPAY_YEAR_MIN} 年以前尚未建立个人账户制度,{BACKPAY_YEAR_MAX} 年以后暂无数据支持。" ) if target_year is None: now = datetime.now() target_year, target_month = now.year, now.month total_personal_principal = 0 total_unit_principal = 0 total_personal_interest = 0 total_unit_interest = 0 total_personal_late_fee = 0 total_unit_late_fee = 0 yearly_results = {} year, month = start_year, start_month while (year < end_year) or (year == end_year and month <= end_month): ``` The command-line parser accepts unrestricted integer and floating-point inputs: ```python parser.add_argument("start_year", type=int, help="补缴起始年") parser.add_argument("start_month", type=int, help="补缴起始月") parser.add_argument("end_year", type=int, help="补缴终止年") parser.add_argument("end_month", type=int, help="补缴终止月") parser.add_argument("--rate", type=float, default=0.6, help="缴费档次比例,默认 0.6(60%%)") parser.add_argument("--all", action="store_true", dest="all_tiers", help="计算全部六档对比") parser.add_argument("--target", type=int, nargs=2, metavar=("YEAR", "MONTH"), help="补缴时间,默认当前年月") parser.add_argument("--monthly-base", type=float, default=None, help="自定义月缴费基数(元),设置后忽略 --rate 和社平工资") ``` The loop advances dates using the following logic: ```python if month == 12: year += 1 month = 1 else: month += 1 ``` ### Technical Analysis The implementation validates only limited year boundaries. It does not enforce: - Months within the valid range of 1 through 12. - A start date that is no later than the end date. - A target ...[truncated 2599 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate every supplied month before entering the calculation loop: ```python def validate_month(name: str, month: int) -> None: if not 1 <= month <= 12: raise ValueError(f"{name} must be between 1 and 12") ``` 2. Convert dates to comparable year-month values and enforce ordering: ```python start_index = start_year * 12 + start_month end_index = end_year * 12 + end_month target_index = target_year * 12 + target_month if start_index > end_index: raise ValueError("The start date must not be later than the end date") if target_index < end_index: raise ValueError("The target date must not be earlier than the end date") ``` 3. Validate numeric inputs with `math.isfinite` and reject zero or negative values: ```python import math if not math.isfinite(base_rate) or base_rate <= 0: raise ValueError("The contribution rate must be finite and greater than zero") if custom_monthly_base is not None: if not math.isfinite(custom_monthly_base) or custom_monthly_base <= 0: raise ValueError("The custom monthly base must be finite and greater than zero") ``` 4. Restrict the contribution rate to the documented supported tiers when a custom rate is not intended: ```python supported_rates = {0.6, 0.8, 1.0, 1.5, 2.0, 3.0} if base_rate not in supported_rates: raise ValueError("Unsupported contribution rate") ``` 5. Represent iteration as a bounded number of months rather than relying on mutable rollover state. Calculate the expected month count after validation and enforce a maximum supported duration. 6. Apply validation inside `calculate_backpay`, not only in the CLI, so Python API callers receive the same protection. 7. Add automated tests covering: - Months below 1 and above 12. - Reversed date ranges. - Target dates before the assessed period. - Negative and zero rates or monthly bases. - NaN and po ...[truncated 116 chars]
