T09 · Insecure Skill Coding Practices
- Location
scripts/manager.py:362- Finding
Unscoped Substring Matching Permits Deletion of Unrelated Calendar Events
- Content
View full analysis
Vulnerability Details
File Location:
scripts/manager.py:362-401
Vulnerability Type: Unvalidated input and overly broad destructive operation
Risk Level: HighVulnerable Code
python def gcal_remove(name): """Remove a hackathon's events from Google Calendar""" setup_zoneinfo() # First, list events to find matching ones output = run_gog(["calendar", "list", "--days", "120", "--max", "200", "--plain"]) if not output: return events_to_delete = [] name_lower = name.lower() for line in output.strip().split('\n')[1:]: # Skip header parts = line.split('\t') if len(parts) >= 4: event_id, summary = parts[0], parts[3] # Match by hackathon name in event summary if name_lower in summary.lower(): events_to_delete.append((event_id, summary)) if not events_to_delete: print(f"❌ No calendar events found for: {name}") return print(f"🗑️ Removing {len(events_to_delete)} events for '{name}':\n") deleted = 0 for event_id, summary in events_to_delete: result = run_gog(["calendar", "delete", "primary", event_id, "--force"]) if result is not None or "deleted\ttrue" in str(result): print(f" ✓ Deleted: {summary}") deleted += 1 else: # Try anyway, gog sometimes returns empty on success check = run_gog(["calendar", "delete", "primary", event_id, "--force"]) print(f" ✓ Deleted: {summary}") deleted += 1The command-line dispatch also permits an explicitly empty argument to reach this function:
python elif subcommand == "remove": if len(sys.argv) < 4: print("Usage: manager.py gcal remove <hackathon-name>") sys.exit(1) gcal_remove(" ".join(sys.argv[3:]))...[truncated 2512 chars]
- Remediation
View remediation
Remediation Suggestions
- Reject empty, whitespace-only, and unreasonably short names before listing or deleting events.
- Resolve the requested hackathon against
hackathons.jsonand require an exact case-insensitive match to a stored hackathon name. - Restrict candidate events to titles that exactly match one of the skill-owned formats:
[REG] <exact hackathon name>[WORK] <exact hackathon name>[DEADLINE] <exact hackathon name>
- Prefer storing event IDs when calendar events are created and delete only those recorded IDs rather than rediscovering events through title searches.
- Display the exact candidate events and require explicit confirmation before destructive deletion, unless the caller supplies a separately controlled and intentional non-interactive flag.
- Remove the duplicate deletion request. Treat success only as a confirmed successful exit status or a documented success response from
gog. - Report failed and successful deletions separately, and never increment the deletion counter when the retry result is unsuccessful or unknown.
- Add tests covering empty input, whitespace-only input, short substrings, unrelated event titles, exact prefixed titles, and failed deletion responses.
