T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/review_planner.py:115
- Finding
- Unbounded Review-Plan Horizon Can Cause Resource Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/review_planner.py`, lines 115-155 **Vulnerability Type**: Uncontrolled resource consumption **Risk Level**: Medium ### Vulnerable Code ```python # Calculate remaining days exam = datetime.strptime(exam_date, "%Y-%m-%d") today = datetime.now() days_remaining = (exam - today).days if days_remaining <= 0: return {"success": False, "error": "考试日期已过或为今天"} # Determine daily study duration daily_hours = daily_hours or DEFAULT_DAILY_STUDY_HOURS # Read the schedule to obtain free slots free_slots_by_day = {} if SCHEDULE_FILE.exists(): with open(SCHEDULE_FILE, "r", encoding="utf-8") as f: schedule_data = json.load(f) free_slots_by_day = schedule_data.get("freeSlots", {}) # Calculate total available time total_available_hours = 0 day_plans = [] day_names = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] for i in range(days_remaining): target_date = today + timedelta(days=i) day_name = day_names[target_date.weekday()] # Obtain free slots for the day free_slots = free_slots_by_day.get(day_name, []) study_slots = get_available_study_time(free_slots, daily_hours) if study_slots: day_plan = { "date": target_date.strftime("%Y-%m-%d"), "day": day_name, "slots": study_slots, "totalMinutes": sum(s["duration"] for s in study_slots) } total_available_hours += day_plan["totalMinutes"] / 60 day_plans.append(day_plan) ``` ### Technical Analysis The `exam_date` argument determines `days_remaining`, but the function imposes no upper limit on the permitted planning horizon. A syntactically valid date far in the future can therefore cause the loop to execute once for every intervening day. For each iteration, the function performs date arithmetic, weekday calculation, schedule lookup, study-slot processing, and potentially appends another object to `day_plans`. If recurring free slots exist, ...[truncated 1472 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Enforce a strict maximum planning horizon before entering the loop. A limit of 365 days, or a smaller value appropriate for an academic term, is sufficient for this use case. 2. Validate that `exam_date` is a string in the required format and return a controlled error for invalid input. 3. Place explicit bounds on `daily_hours`, chapter counts, and chapter-name lengths to prevent related resource-abuse conditions. 4. Avoid retaining all intermediate daily plans when they are not needed. Generate and process entries incrementally where practical. 5. Add tests for boundary dates, invalid dates, leap years, past dates, and dates beyond the supported horizon. Example hardening: ```python MAX_PLANNING_DAYS = 365 try: exam = datetime.strptime(exam_date, "%Y-%m-%d") except (TypeError, ValueError): return {"success": False, "error": "Invalid exam date"} days_remaining = (exam.date() - datetime.now().date()).days if days_remaining <= 0: return {"success": False, "error": "Exam date must be in the future"} if days_remaining > MAX_PLANNING_DAYS: return { "success": False, "error": f"Planning horizon cannot exceed {MAX_PLANNING_DAYS} days" } ``` ]]>
