Back to skill

Security audit

WideHive

Security checks for vulnerabilities and agentic risk

Overview

WideHive is a disclosed wide-research automation skill, but Review is warranted because unvalidated target slugs and spreadsheet exports can create unintended local file access or CSV formula risks with untrusted inputs.

Install only if you are comfortable granting this skill web access, sub-agent spawning, and workspace file read/write for large research runs. Keep run directories contained, accept target lists only from trusted sources, require slugs to use a safe filename pattern such as letters, digits, underscores, and hyphens, and be cautious opening generated CSV files in Excel or similar apps unless formula-like cells have been neutralized.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/merge_results.py:56
Finding
Path Traversal Through an Unvalidated Target Slug<![CDATA[ ## Vulnerability Details **File Location**: `scripts/merge_results.py`, lines 56–68 **Vulnerability Type**: Path traversal and unintended local file disclosure **Risk Level**: Medium ### Vulnerable Code ```python for t in targets: slug = t.get("slug", "") if not slug: defects.append({"slug": "?", "issues": ["target_without_slug"]}) continue f = result_dir / f"{slug}.json" if not f.exists(): missing.append(slug) continue try: data = json.loads(f.read_text(encoding="utf-8")) except Exception as e: defects.append({"slug": slug, "issues": [f"json_parse_error: {e}"]}) continue ``` ### Technical Analysis The `slug` value is loaded from the run's `targets.json` file and inserted directly into a filesystem path: ```python f = result_dir / f"{slug}.json" ``` The code does not enforce a filename-safe slug format and does not resolve the resulting path to verify that it remains inside `result_dir`. Consequently, a slug containing parent-directory components such as `../` can escape the intended result directory. Depending on `pathlib` path-composition behavior, an absolute path supplied as a slug can also replace the intended base path. The `.json` suffix limits the issue to paths ending in that suffix, and the selected file must contain valid JSON to be processed successfully. Nevertheless, many application configuration, metadata, credential, and state files use JSON and could be exposed. ### Attack Path 1. An attacker gains the ability to supply or modify a run's `targets.json`, such as through an untrusted tabular intake or target-list input. 2. The attacker assigns a target a traversal slug, for example: ```json { "slug": "../../sensitive/config", "name": "Injected target" } ``` 3. A user or agent executes the documented merge operation: ```bash python scripts/merge_results.py --run-dir /path/to/run ``` 4. The script constructs a path ...[truncated 944 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a conservative slug allowlist before any path construction: ```python SLUG_RE = re.compile(r"^[A-Za-z0-9_-]+$") if not isinstance(slug, str) or not SLUG_RE.fullmatch(slug): defects.append({"slug": str(slug), "issues": ["invalid_slug"]}) continue ``` 2. Resolve both the result directory and candidate file, then enforce direct containment: ```python result_root = result_dir.resolve() candidate = (result_root / f"{slug}.json").resolve() if candidate.parent != result_root: defects.append({"slug": slug, "issues": ["slug_path_escape"]}) continue ``` 3. Reject absolute paths, path separators, `.` and `..` components explicitly, even if an allowlist is used. 4. Apply the same slug validation when creating `targets.json` and when workers select their output paths. Validation at ingestion improves usability, while validation at file access remains necessary as a security boundary. 5. Add regression tests covering: - `../outside` - nested paths such as `subdir/file` - absolute paths - Windows separators and drive paths - valid slugs containing letters, numbers, underscores, and hyphens ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/merge_results.py:83
Finding
Spreadsheet Formula Injection in Generated CSV Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/merge_results.py`, lines 83–106 **Vulnerability Type**: CSV/spreadsheet formula injection **Risk Level**: Medium ### Vulnerable Code ```python row = {"slug": slug, "name": t.get("name", data.get("target", "")), "scenario": scenario} for k in fields: v = fd.get(k) if isinstance(v, (list, dict)): row[k] = json.dumps(v, ensure_ascii=False) else: row[k] = "" if v is None else v row["n_sources"] = len(data.get("sources") or []) rows.append(row) records.append(data) out_json = run / "merged.json" out_csv = run / "merged.csv" out_json.write_text( json.dumps({"scenario": scenario, "fields": fields, "records": records}, ensure_ascii=False, indent=2), encoding="utf-8") if rows: cols = ["slug", "name", "scenario"] + fields + ["n_sources"] with out_csv.open("w", newline="", encoding="utf-8-sig") as fh: w = csv.DictWriter(fh, fieldnames=cols) w.writeheader() for r in rows: w.writerow(r) ``` ### Technical Analysis Target names, slugs, scenario values, and worker-generated field values are written directly to `merged.csv`. Worker fields can originate from externally controlled web pages or other researched material. Spreadsheet applications may interpret cells beginning with formula-control characters—commonly `=`, `+`, `-`, or `@`—as executable formulas. The Python CSV writer correctly escapes CSV syntax, but CSV quoting does not reliably prevent Excel and similar applications from evaluating formulas. Because the project explicitly produces a UTF-8-SIG CSV intended to open directly in Excel, spreadsheet interpretation is part of the expected workflow. A malicious source can therefore place a formula-like value in a researched field and have it carried into the generated CSV. ### Attack Path 1. An attacker controls content on a page, document, repository, or other object selected for research. 2. ...[truncated 1544 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Neutralize all string cells before writing CSV, including metadata columns and dynamic fields: ```python FORMULA_PREFIXES = ("=", "+", "-", "@") def csv_safe(value): if not isinstance(value, str): return value if value.lstrip().startswith(FORMULA_PREFIXES): return "'" + value return value ``` 2. Apply the function to every value passed to `DictWriter`: ```python for r in rows: w.writerow({key: csv_safe(value) for key, value in r.items()}) ``` 3. Consider treating leading tabs, carriage returns, newlines, and other whitespace carefully because some spreadsheet applications ignore leading whitespace before identifying a formula. Normalize or inspect the first significant character. 4. Keep the original values unchanged in `merged.json` so the machine-readable artifact remains faithful to the research data. Formula neutralization should occur only at the spreadsheet export boundary. 5. Document that the CSV is a presentation artifact with formula-neutralized cells. 6. Add regression tests for values beginning with `=`, `+`, `-`, and `@`, including variants preceded by whitespace, tabs, carriage returns, or newlines. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description emphasizes an active orchestration system for large-scale research: launching many context-isolated sub-agents, merging their outputs, and producing shaped reports. The supplied code does not perform those tasks. It only discovers existing run directories, parses already-produced JSON artifacts, and writes a consolidated corpus and index. This is a materially different primary purpose: corpus consolidation of finished runs rather than wide research orchestration or report synthesis. The file operations are consistent with local post-run processing, and there are no suspicious undeclared external accesses, but the main behavior still does not match the declared skill description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents the skill as a broad research orchestration system that dispatches many context-isolated sub-agents, performs batch research, merges outputs programmatically, and synthesizes scenario-specific reports. The supplied code chunk does not perform any of those core behaviors. Instead, it only loads an existing merged.json artifact and renders it into an interactive HTML dashboard using embedded CSS/JavaScript, including search, sorting, detail views, and up to two simple numeric charts. This is related to presentation of WideHive outputs, but it is materially narrower and different from the declared primary purpose. Therefore the description does not accurately represent what this code chunk actually does.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill explicitly instructs workers to read and write files across a workspace run directory, but it does not declare any tool scope or allowed-tools boundaries. That creates an authorization ambiguity where an agent runner may grant broader file capabilities than intended, increasing the chance of unintended file access or overwrite if prompts, paths, or surrounding harness behavior are manipulated.

Scope Creep

Low
Category
Excessive Agency
Content
```
You are a Wide Research single-object worker. Handle ONLY this one object;
do not expand scope.

Object: <name> (<url or unique identifier>)
Task:
Confidence
75% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This code emits a generated HTML document with the root element fixed to `lang="en"`. The file contains no user opt-in, configuration option, or documented reason for forcing English, which matches the language/locale policy violation category.

Static analysis

No suspicious patterns detected.