Back to skill

Security audit

Hackathon Manager

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent hackathon tracker, but it needs review because its Google Calendar removal command can force-delete unrelated calendar events.

Install only if you are comfortable with this skill storing hackathon data locally, fetching URLs you provide, and using an authenticated gog CLI to access Google Calendar. Treat gcal sync and especially gcal remove as high-risk operations: review the exact events first, avoid short or empty names, and prefer a dedicated calendar or manual deletion until the removal logic is narrowed to stored event IDs or exact skill-owned titles.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
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: High

Vulnerable 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 += 1

The 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

  1. Reject empty, whitespace-only, and unreasonably short names before listing or deleting events.
  2. Resolve the requested hackathon against hackathons.json and require an exact case-insensitive match to a stored hackathon name.
  3. 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>
  4. Prefer storing event IDs when calendar events are created and delete only those recorded IDs rather than rediscovering events through title searches.
  5. Display the exact candidate events and require explicit confirmation before destructive deletion, unless the caller supplies a separately controlled and intentional non-interactive flag.
  6. Remove the duplicate deletion request. Treat success only as a confirmed successful exit status or a documented success response from gog.
  7. Report failed and successful deletions separately, and never increment the deletion counter when the retry result is unsuccessful or unknown.
  8. Add tests covering empty input, whitespace-only input, short substrings, unrelated event titles, exact prefixed titles, and failed deletion responses.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description omits significant behavior: Google Calendar access, creation and deletion of external events, and reliance on external fetching/workflows not actually implemented in the described command surface. This mismatch can mislead users and higher-level policy systems about what the skill can do, causing unexpected side effects in external accounts and weakening informed consent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill invokes an external executable and can create or delete Google Calendar events, including forced deletions, which is a materially powerful capability not justified by the stated purpose alone. In an agent context, this creates a dangerous side-effect surface where compromised inputs, mistaken invocations, or user confusion could lead to unauthorized remote actions and potential execution of an attacker-controlled helper binary.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill describes use of shell commands, local file reads/writes, environment access, and external tooling, but does not declare any explicit tool scope or permissions boundaries. That creates an overbroad execution surface where an agent may invoke powerful capabilities implicitly, reducing auditability and increasing the chance of unintended filesystem or command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The markdown instructs the agent to fetch external URLs and later modify Google Calendar, but it does not clearly warn about network access, data ingestion from untrusted pages, or external side effects. Users may not realize that providing a link can trigger remote fetching and persistence of extracted content, or that later commands can alter calendar state.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill persists and synchronizes hackathon data into Google Calendar, creating durable external state beyond the current session. Persistent external changes can outlive the conversation, clutter or overwrite user calendars, and be difficult to review or reverse if triggered unintentionally or with incorrect extracted data.

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

python scripts/manager.py gcal sync

text

Create Google Calendar events for all tracked hackathons:
- `[REG]` - Registration opens (timed event)
- `[WORK]` - Work period (all-day event)
- `[DEADLINE]` - Submission deadline (timed event)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The activation guidance uses broad triggers like 'when user mentions hackathons' and common phrases such as 'what's due?' or 'what hackathons?', which can cause the skill to activate in loosely related conversations. Overbroad triggering increases the risk of unnecessary file access, network fetches, or calendar operations without sufficiently clear user intent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill includes Google Calendar listing, creation, and deletion functionality, which extends beyond simple local hackathon tracking and checklist management. This expands the skill's authority to remote data access and modification, increasing the risk of unintended disclosure or tampering with a user's calendar if the capability is invoked unexpectedly.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/manager.py (reported line 283)May include surrounding context.

python
# Try PATH
    try:
        result = subprocess.run(["where" if sys.platform == "win32" else "which", "gog"], 
                               capture_output=True, text=True)
        if result.returncode == 0:
            return result.stdout.strip().split('\n')[0]

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
78% confidence
Finding

The code executes an external binary whose path may be resolved from user-controlled locations such as PATH or writable home-directory paths. While arguments are passed safely as a list, the trust boundary is weak: a malicious local program named 'gog' could be executed and would inherit the user's privileges, leading to arbitrary code execution or unauthorized calendar actions.

Content

Scanner excerpt · scripts/manager.py (reported line 302)May include surrounding context.

python
return None
    
    try:
        result = subprocess.run([gog] + args, capture_output=True, text=True)
        if result.returncode != 0:
            print(f"❌ gog error: {result.stderr}")
            return None

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Calendar deletion is performed with '--force' and no confirmation, and the matching logic deletes any event whose summary contains the provided name substring. This combination makes accidental or overbroad deletion more likely, especially in an agent workflow where names may be ambiguous or partially matched, causing unintended loss of calendar data.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.