Back to skill

Security audit

World Meeting Coordination Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward local meeting-window helper with disclosed settings storage, though users should avoid invalid numeric options that can hang the script.

Install only if you are comfortable with the skill saving your meeting timezone, hours, and flexibility in its disclosed OpenClaw config file. Confirm setup/update requests before changing settings, and use positive values for --step, --duration, and --top until input validation is added.

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

Warning
Location
scripts/meeting_windows.py:131
Finding
Unbounded Resource Consumption Through Unvalidated Step Size## Vulnerability Details **File Location**: `scripts/meeting_windows.py`, lines 131 and 195–211 **Vulnerability Type**: Improper input validation leading to uncontrolled resource consumption **Risk Level**: Medium ### Vulnerable Code ```python ap.add_argument("--step", type=int, default=60) ``` ```python slots = [] t = start_day end_day = start_day + timedelta(days=1) while t < end_day: t2 = t + timedelta(minutes=args.duration) score = 0 reasons = [] rows = [] for p in participants: ls, le = t.astimezone(p.tz), t2.astimezone(p.tz) pref_start, pref_end = hours_map.get(p.name, default_hours) flex = me_flex if p.name in hours_map and (pref_start, pref_end) == hours_map.get(p.name) else "balanced" pen = penalty(ls, pref_start, pref_end, flex) score += pen r = reason_for_penalty(p.name, pen, ls) if r: reasons.append(r) rows.append((p.name, ls, le)) slots.append((classify(score), score, t, t2, rows, sorted(set(reasons)))) t += timedelta(minutes=args.step) ``` ### Technical Analysis The `--step` argument is parsed as an arbitrary integer but is never checked to ensure that it is positive. The loop terminates only when `t` reaches `end_day`, and its sole progress operation is: ```python t += timedelta(minutes=args.step) ``` If `--step 0` is supplied, `t` never changes. If a negative step is supplied, `t` moves farther away from `end_day`. In both cases, the loop cannot terminate normally and continuously appends generated slot records to the `slots` list. This creates an uncontrolled resource-consumption condition involving sustained CPU use and unbounded memory growth. The vulnerability is reachable directly through documented CLI execution when an untrusted caller can influence arguments. ### Attack Path 1. An attacker or untrusted caller invokes the meeting-window script. 2. ...[truncated 1331 chars]
Remediation
## Remediation Suggestions Validate numeric CLI arguments before any processing. At minimum, require `--step` to be greater than zero. A reusable `argparse` validator can reject invalid input before entering the loop: ```python def positive_int(value: str) -> int: parsed = int(value) if parsed <= 0: raise argparse.ArgumentTypeError("value must be a positive integer") return parsed ap.add_argument("--step", type=positive_int, default=60) ap.add_argument("--duration", type=positive_int, default=60) ap.add_argument("--top", type=positive_int, default=3) ``` Apply reasonable upper and lower bounds as appropriate for the intended interface. For example, constrain slot step and duration values to a supported scheduling range and cap the number of generated slots independently of user input. Add a defensive iteration limit so future logic changes cannot create another unbounded loop: ```python max_slots = 1440 generated = 0 while t < end_day and generated < max_slots: # Generate slot. t += timedelta(minutes=args.step) generated += 1 ``` Add automated tests confirming that zero and negative values are rejected promptly and do not start slot generation. If this CLI is invoked by a service, also enforce process-level timeouts and memory limits as defense in depth.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (3)

Vague Triggers

Medium
Confidence
93% confidence
Finding
The listed alternate setup phrases are broad enough that normal user requests about scheduling preferences or timezones could be misclassified as a configuration/setup command. That can cause unintended writes to local configuration or trigger an unexpected onboarding flow, which is a real safety and integrity issue even though it is not a code-execution bug.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises capabilities that involve reading and writing a user-scoped config file, but it does not explicitly declare any tool scope or permissions boundary in the manifest. That creates an authorization ambiguity: an agent or platform may permit broader file access than the skill actually needs, increasing the risk of unintended local file access or persistence.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
cfg = load_config()

    if args.setup or (not cfg and __import__("sys").stdin.isatty()):
        cfg = run_onboarding_interactive()

    if args.show_settings:
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Static analysis

No suspicious patterns detected.